22 October 2020, 19:01 | #1 |
Registered User
Join Date: May 2017
Location: AmigaLand
Posts: 459
|
Math [divs]
Hi,
Some problem I've got with divs instructions. I'd like to divide 2 numbers in order to add them sequentially, a kind of linear interpolation. I wrote this code : Code:
move.w #101,d0 move.w #100,d1 ext.l d asl.l #8,d0 asl.l #6,d1 divs d1,d0 clr.w d0 asr.l #2,d0 I need to have result of iteration in 16:16 format so I could use a simple SWAP within interpolation loop instead of arithmetic shifts. So my question is, why I lose precision ? for instance the result in D0 = $00010000 which means in my choice of decimal precision D0 = 1. the decimal part should be around $28F ($0001028F). The strange thing is also when I calculate the inverse of this divsion we get a worse approximation. I could get a better precision avoiding the ASL of D1 but I expercience overflow errors more easily. I suspect I'm using bad precision choices but I'm not sure. Any hints you Amiga coders ? |
22 October 2020, 19:33 | #2 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,039
|
The problem is you that are nuking the relevant part with clr.w d0. For a more detailed insight, look up fixed point math.
In general... For example, say you are using format 24:8: 24 bits int, 8 bits fraction (so, all numbers are multiplied by 256, precision is 1/256). Every arithmetic operation will require *normalization* of the result: 1. add/sub: auto-normalized, nothing do to 2. mul: result is 16:16 so you have to divide it by 256 (right-shift 8 times) 3. div: pre/post-normalization is required because after the div it's too late (fraction is nuked), mul the dividend by 256 (left-shift 8 times) Code:
move.l #100<<8,d0 ; 24:8 move.l #101<<8,d1 ; 24:8 ; add/sub move.l d0,d2 add.l d1,d2 ; d2 is 24:8, done ; mul muls.w d1,d0 ; d0 is 16:16 asr.l #8,d0 ; d0 is 24:8, normalized ; div asl.l #8,d0 ; d0 is 16:16 divs.w d1,d0 ; d0 is 8:8 ext.l d0 ; d0 is 24:8 |
22 October 2020, 20:32 | #3 |
Registered User
Join Date: May 2017
Location: AmigaLand
Posts: 459
|
Well, according to my 68000 book, the upper 16 bits of divs result is the rest. I understand it like a divs is a succession of subtractions (like in decimal) and when it's too small this amount is placed in upper word.
My bad, I just checked, I transcibed with a missing swap before the clr.w. I forgot this ext.l, wasn't a problem for the moment until I use negatives numbers. Anyway many thanks for taking time to write your example, I'll investigated further using your code. Edit : "I forgot this ext.l, wasn't a problem for the moment until I use negatives numbers." : There, I was speaking about the ext.l right after the divs Last edited by LeCaravage; 22 October 2020 at 22:37. |
23 October 2020, 08:39 | #4 |
Registered User
Join Date: May 2017
Location: AmigaLand
Posts: 459
|
@a/b : You' da man ! It works. By analysing my mistakes it seems it was a pb of precision, I missed the additional asl.l #8,d0 you did. Now I have quite accurate result
Also I had to reduce divisor precision, 24:8 was too much. Cheers, |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Discovery: Math | Audio Snow | request.Old Rare Games | 30 | 20 August 2018 12:17 |
Math library? | Tiddlypeeps | Coders. General | 5 | 08 April 2010 19:45 |
la bosse des math ? | turrican3 | request.Old Rare Games | 1 | 26 May 2007 06:58 |
Math apps | mtb | support.Apps | 1 | 08 September 2002 18:59 |
|
|