If i have a no like 1.1234 in decimal how do i convert it to binary? I am interested in the fractional part cause even the windows calculator cant do that.
Posted on 2001-09-19 09:50:17 by MovingFulcrum
Heh... I remember some exercices I made at school about representation of floating point in binairy.

There certainly is a better way to figure out what is the fpart of a number in binairy (maybe a special instruction), but here is the theory I know.

Example: representation of 76.875 as a 32bit number

Bit 31 is the sign: 0 for positive, 1 for negative
Bits 30~23 represent the exponent augmented by 127
The rest (bits 22 to 0) represent the mantissa (the actual number)

First, you can convert your decimal number in hex:
76.875 = 0x4C.E (4*16 + 12 + 14*16^-1)

Then, you convert the hex number in binary
0x4C.E = 0100 1100.1110 000 -> 1.0011 0011 1000 * 2^6

As I said, the exponent (e) is represented as e+127
6+127 = 133 -> 1000 0101

Now, we have all the data we need to represent the number:
0 1000 0101 0011 0011 1000

Maybe I'm wrong... I learned this a while ago :grin:
Posted on 2001-09-19 10:54:45 by dotCODE
ooops... I forgot some "0" at the end of the final binary number.

It's 0 1000 0101 0011 0011 1000 0000 0000 000

Posted on 2001-09-19 10:56:44 by dotCODE
I might be sounding very stupid here but i really couldnt get you.

Where does 127 come into play?
How does 0100 1100.1110 000 change to 1.0011 0011 1000 * 2^6 ?

In 6+127 = 133 -> 1000 0101
Where does 6 come from?

Could you please explain this once again?
Posted on 2001-09-19 14:35:19 by MovingFulcrum
check out "What Every Computer Scientist Should Know About
Floating-Point Arithmetic". It's available on the net, filename someting
like WECSSKAFloatingPoint.pdf.
Posted on 2001-09-19 14:59:29 by f0dder
Of course, a real book is much better, but I'll try to explain my point.

First, for the "127" thing. Maybe it's better to see the 32bits as this:

bit 31: sign of the number (1=negative, 0=positive)
bit 30: sign of the exponent (the reason to add "127")
bits 29~23: exponent (with bit 30, range from -127 to 128)
bits 22~0: mantissa

For the "2^6" thing.
I'll start with a decimal number: 1234.56
You can also write this number as 1.23456 * 10^3, right?

What is the "10"? It's the base (10 different symbols)
And the "3"? It's the exponent of the base

Same rule for the binary, but instead of 10 symbols, you only have 2: 0 and 1

So 1100.11101 is the same thing as 1.1001 1101 * 2^3
2 is the base, 3 is the exponent

I'm really sorry if this do not help... I just dont know much english vocabulary to write clearly enough :(
Posted on 2001-09-19 15:34:46 by dotCODE
hmm... That was MUCH better. Now i get it. Thanks a lot. Just one problem though-
When a put 1000 0101 0011 0011 1000 0000 0000 000
in the windows calculator it shows me 2234744832 in decimal???? Why doesnt it show me the real fractional no?

Also in 1100.11101 we know that this is a fractional no but how does the cpu know? I mean the computer doesnt know anything called a ".". It just knows 1 and 0? So how does it get to know abt the "." in between.

As for the book. I downloaded it and it doesnt explain anything about deciaml to binary conversion. Also by the time you finish it you would have done a PHD in floating point:grin: But anyway thanks for the reply f0dder:)
Posted on 2001-09-19 15:58:32 by MovingFulcrum
Of course, there is no concept of "." in a 32bit register...
And, as I understand it, you can't just take bits 23 to 0 and simply display the decimal part of the number.

Why? The exponent calculation is reversed after the dot. Ok, I'm confused myself, so here is what I mean:

1101 means (1*2^0) + (0*2^1) + (1*2^2) + (1*2^3) = 13
If you put extra digits at the left (0000 1101), this do not change the actual value of the number... but if you add extra digits at the end (1101 0000), you obtain a much bigger number:

(1*2^7)+(1*2^6)+(1*2^4) = 208 (I removed the 0*2^...)

After the ".", it's reversed. Adding extra digits at the left (0.0000 1101) of the fpart DO change the value of your number:

(1*2^-5)+(1*2^-6)+(1*2^-8) = 0.050781

I don't know all the instructions of a x86 cpu, but I hope there is a way to do all thoses calculations "automatically". If not, it will be a great project for me to do a routine who will handle this :grin:
Posted on 2001-09-19 16:40:32 by dotCODE
Don't forget about binary fractions:

2^-1 = .5
2^-2 = .25
2^-3 = .125
2^-4 = .0625
2^-5 = .03125
   . . .
2^-32 = 0.00000000023283064365386962890625 (approx?)
Posted on 2001-09-19 21:25:28 by eet_1024
Sorry, i couldnt get what you intend to explain in your post eet. I know there are binary fractions but how does the cpu know its a fraction. How does it know about THE DOT("." symbol). Also when i input the fractional binary in windows calculator why do i get a whole no?
Posted on 2001-09-20 03:17:32 by MovingFulcrum
Forget the DOT! It's only used so humans can read the floating point numbers.
Posted on 2001-09-20 05:49:07 by gliptic
MovingFulcrum, the computer doesn't know anything about dot, that is why a bias is choosen. This is where the name 'fixed-point' comes from - you choose a bias and fix the point to a certain value. Then you code your algorithms to that bias. If you use an existing number format then you need to write your code to the bias of that format.

For example, if we decide to have the following bias:
00 00 00.00 ;This is a dword.

then when you multiple to numbers of this type you would get a number in this form:
00 00 00 00 00 00.00 00 ;qword

To get back to the original form we would need to shift the number right eight places. Try this code to see for yourself:
fd8mul PROC Num1:DWORD,Num2:DWORD

mov eax,Num1
mul Num2
push eax
push edx
mov eax,3[esp]
add esp,8
fd8mul ENDP

invoke fd8mul,0480h,0280h ; 4.5 * 2.5 = 11.25
;eax = 0B40h = 11.25
This number format is biased by 1/256. If you want to convert a decimal number to this format on a calculator then you have to multiply it by 256. Try it: 11.25 * 256 = 0B40h. :)
Posted on 2001-09-20 08:37:01 by bitRAKE
Ok i finally get it!
Thanks a lot bitRake and everyone posting on this thread for helping me out:)
Posted on 2001-09-20 11:56:44 by MovingFulcrum
Here is another view.

The "." is implied by the exponent field.

To convert an FP number to its true binary form, do the following:

1) The leading bit is the sign, 1 = '-', 0 = '+'.
2) Take the exponent field as an unsigned value and subtract the bias (127 for 32-bit, 1023 for 64-bit). The resulting signed value is your true exponent.
3) Take the mantissa field and, on the left, add the two characters '1.' -- a "one" bit and a binary point.
4) If the true exponent is positive, move the binary point that many bits to the right, adding zeroes as necessary.
5) If the true exponent is negative, move the binary point that many bits to the left, adding zeroes as necessary.
6) The adjusted mantissa is your true binary number.

The above steps are for normalized numbers. If the exponent is 0, the conversion follows rules for unnormalized numbers. Zero is an unnormalized number.

There are also some NaN (not a number) values.
Posted on 2001-09-20 14:45:28 by tank
hmm... That was nice tank but its still not crystal clear in my mind. Anyway i was going through the masm docs on floating point and it explains pretty well. I saw a diagram which i have put below. If anyone could complete this diagram replacing the corrupted grayed out boxes with actual digits, it could go a long way in explaining the concept. Thanks in advance to anyone who does it.
This is from chapter6 of the masm documeantation, fig 6.1.
Posted on 2001-09-21 02:22:40 by MovingFulcrum