Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > $0DD0 * 0.1234567890 in assembly. How to?
2013-06-10 07:04
Flavioweb

Registered: Nov 2011
Posts: 463
$0DD0 * 0.1234567890 in assembly. How to?

Taking into account the fair compromise of precision, what is the fastest and shortest method for multiplying a 16bit value for a floating point number like 0.1234567890?

Please explain it as if you were writing the book "arithmetic for dummies with 6502/10". Tnx.
2013-06-10 07:23
JackAsser

Registered: Jun 2002
Posts: 2014
Quote: Taking into account the fair compromise of precision, what is the fastest and shortest method for multiplying a 16bit value for a floating point number like 0.1234567890?

Please explain it as if you were writing the book "arithmetic for dummies with 6502/10". Tnx.


You explicitly say floating point number? Are you sure you know it is a floating point number, if so, in which format, which standard? It's by far easier to use fixed point numbers. Just as with binary where each digit has a value of 2^x the decimal part will have a value of 2^-1.

So for example with an 8.8 fixed point number you have 8 bits for the integer part and 8 bits for the fraction part:

iiiiiiii.ffffffff

So the fraction part can express as small values as 1/256.

Now, to multiply this with a 16-bit integer number, simply do a 16bit * 16bit multiply. The number of incoming integer bits will correspond to the number of outcoming integer bits, same holds for fraction bits. You will input 16 integer bits and another 8 integer bits, giving a total of 24 bits. The fractional input is 8 bits, so you have 8 bits fraction in the result also.

So: 16.0 * 8.8 = 24*8 in terms of bit precision of the integer.fractional parts.

So, unless you're forced to perform floating point, consider use fixed point instead. And then use my multiplication routines at: http://codebase64.org/doku.php?id=base:seriously_fast_multiplic..
2013-06-10 07:57
Oswald

Registered: Apr 2002
Posts: 5094
fastest and shortest way is not to do it. no demo or game code out there does stuff like this. you have to be clever and find a simpler way to do what you want: reducing precision to 8bit*8bit or making use of tables, or just go around it.

and what jackasser said. :)
2013-06-10 08:33
JackAsser

Registered: Jun 2002
Posts: 2014
Quote: fastest and shortest way is not to do it. no demo or game code out there does stuff like this. you have to be clever and find a simpler way to do what you want: reducing precision to 8bit*8bit or making use of tables, or just go around it.

and what jackasser said. :)


The 3D-engine in Andropolis is all about 8.8*8.8 and 8.8 / 8.8. :)
2013-06-10 09:10
Flavioweb

Registered: Nov 2011
Posts: 463
So...
if i need to multiply with "fixed point" the value $0DD0 * 0.12345 i must treat $0DD0 if it's $0D.$D0 and multiply for ... what? $D0*12345 and... $0D*$00 ?

Someone can explain... please?
2013-06-10 09:27
Fresh

Registered: Jan 2005
Posts: 101
It highly depends on what you want to achieve, however you can proceed this way:
- Use 16 bits to represent 0.1234567890 (0 bit at the left of the decimal point and 16 at the right)
- Use 16 bits to represent $DD00 (16 bit at the left of the decimal point and 0 a the right)
This way you need to multiply the following numbers:

$1F9Ax$DD00

Use Jackasser's routine and then consider the 32 bit results as a 16.16 fixed point value.
It's like doing ie 0.5*5: you compute 5*5 ant then you move the decimal point position of the result according to multipliers.
2013-06-10 09:50
Oswald

Registered: Apr 2002
Posts: 5094
Quote: So...
if i need to multiply with "fixed point" the value $0DD0 * 0.12345 i must treat $0DD0 if it's $0D.$D0 and multiply for ... what? $D0*12345 and... $0D*$00 ?

Someone can explain... please?


0.5*5.0 is a good example. multiply 0.5 with 10 you get 5. 5*5=25 divide the result with 10, you get 2.5.

now do the same with 256.

1. 0.123456789*256=31.
2. 31*0dd0= 109616.
3. 109616 / 256 = 428

checking the result: dd0*0.123456789 = 436

the difference between the result is the precision loss of using only 8.8 bits math. (throwing away the fraction at the *256 step, hence you can not have fraction in a byte)

note that you dont need to actually divide by 256. dividing by 256 is equal to shifting the bits 8 times to the right. but as we are working with bytes, the multiply result is already using several bytes. just use the part of the result which represents the shifting already.

if you need more precision you have to use a bigger number than 256.
2013-06-10 10:16
Fresh

Registered: Jan 2005
Posts: 101
In my last post I've written $DD00 instead of $0DD0: it's a stupid typo, consider every occurence of $DD00 as $0DD0.
2013-06-10 14:26
JackAsser

Registered: Jun 2002
Posts: 2014
Quote: So...
if i need to multiply with "fixed point" the value $0DD0 * 0.12345 i must treat $0DD0 if it's $0D.$D0 and multiply for ... what? $D0*12345 and... $0D*$00 ?

Someone can explain... please?


It's really basic math. Consider the numbers 15*73. To multiply these you write the following:
   15
  *73


First you do 3*5 = 15. Save the 1-digit:
   15
  *73
-----
    5


Then you do 3*1 = 3 (+1 from previous multiplication) = 4:
   15
  *73
-----
   45


Then you do 7*5 = 35. Save the 3-digit:
   15
  *73
-----
   45
   5


And finally you do 7*1 = 7 (+3 from the previous mul) = 10:
   15
  *73
-----
   45
 105



Then you add them together: 1050 + 45 = 1095.

Now with decimals, f.e. 1.5 * 7.3 you would do exactly the same and end up with 10.95. Or if you did 15*7.3 you would get 109.5.

Now instead of treating each digit as a 10-base value, simple treat it as a 256-base value. (i.e. each byte is a digit). And do EXACTLY the same.

There's nothing more to it really.
2013-06-11 15:18
Frantic

Registered: Mar 2003
Posts: 1648
Amen!
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
crayon/Hokuto Force
csabanw
goto80/HT
DanPhillips
Peacemaker/CENSOR/Hi..
Holy Moses/Role
Guests online: 101
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.6)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Dawnfall V1.1  (9.5)
7 Rainbow Connection  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Triad  (9.3)
5 Censor Design  (9.3)
Top Swappers
1 Derbyshire Ram  (10)
2 Jerry  (9.8)
3 Violator  (9.7)
4 Acidchild  (9.7)
5 Cash  (9.6)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.045 sec.