hey all again

how can i convert from a DWORD in memory to a float with decimal part ?

i did this :
 push eax
fild dword ptr
fadd myvar
fstp myvar
pop eax

and i got the integer .. right

but what about the "." ?

i mean
lets say i wanna have the value in REAL : "1.5f"
and my DWORD is formed by 2 words, the hight word would be the "1" and the low "5" ie : 00010005
how can i convert 00010005h to 1.5f in the FPU ?

thx
Posted on 2006-06-10 17:01:09 by GR33d
If you are really interested in using the FPU on your own, I would strongly suggest that you first get familiar with the format of the floating point data types and how various data types are handled by the FPU. Have a look at some of the chapters in the following. Simply ask if you need any clarification.

http://www.ray.masmcode.com/fpu.html

Raymond
Posted on 2006-06-10 22:13:14 by Raymond
You can use the fpu to perform data type conversions if you want to get some instant satisfaction without learning all about mantissa bits and other vaguiaries of the fpu binary formating.

First, know that the fpu only works with REAL (floating) values.
Use fild (instead of fld) to load an integer onto the fpu - it's now in REAL form on the fpu stack, NOT INTEGER.
After you finish screwing around, if you want to spit the value out as a (rounded) integer, use fistp (instead of fstp) :)

.data
fp1pt5 REAL4 1.50f
myinteger dd 27065
myanswer dd 0
.code
fild myinteger
fmul fp1pt5 ;fimul is also available!
fistp myanswer

There, we just multiplied 27065 * 1.5 and stored the answer as an integer, wasn't that fun?
Posted on 2006-06-10 23:59:51 by Homer
but how would i make a compost value from a dword ?

im trying :
	
mov split,eax
fild word ptr
fild word ptr


but i dont know for what value should i divide ( fdiv ) : 10f.. 100f so i can make the decimal part from it...
Posted on 2006-06-11 09:10:58 by GR33d
You are confused indeed, I get the impression you are referring to a quite dated idea called 16:16 fixedpoint math - this is quite different from how REALX values are encoded.

Let's say for example though, that you had some value encoded in 16:16 form, such that the high word contained the 'integer' and the low word contained the 'fraction'..

.data
fp1 REAL4 1.0f
MyFloatingValue REAL4 0.0f

.code
lea eax,split ;eax points to our 16:16 fixedpoint value
;Let's create a Fraction using the low word
;That's like saying 1/X where X is the low word
fld fp1 ;fpu contains 1.0f
fidiv word ptr ;fpu contains 1/X (fraction)
fadd word ptr  ;add the integer part of the value
fstp MyFloatingValue ;and store the result as a REAL

Does that help at all?
Posted on 2006-06-11 11:36:29 by Homer
Well, this is a bit of a poser, I have figured out how to generate the integer part of the REAL4 but not the fractional part yet, if anyone has any ideas ...

// EAX contains the fixed point number (IIIIFFFFh)
// First split at the point
movzx ecx,ax
mov ,ecx
shr eax,16
movsx eax,ax
mov ,eax

// Test for sign store in ebx
xor ebx,ebx
test eax,eax
jns >
    mov ebx,080000000h ; sign bit of REAL4
    neg eax
:

// Calculate the exponent
bsr edx,eax
add edx,127
// Shift the exponent to the left 22 bits
shl edx,23

// merge the two parts
mov eax,

// Calculate the highest bit in the number
bsr esi,eax
mov ecx,23
sub ecx,esi
shl eax,cl
mov ,eax

// Calculate the fractional component
; ?????????????

// Build the REAL4
or ,ebx
or ,edx
Posted on 2006-06-11 14:25:18 by donkey
Well,

I can't figure your problem out. The fixed point you are using is pretty bad, you should be using a more conventional standard for fixed point. The problem is that if you have 0007h in the low order of the DWORD how is it possible to know whether you mean 0.0000000000000111 or 0.111 or even 0.00000111 ? You would have to have a crystal ball to decode the fractional part of the fixed point. There are many tutorials on fixed/floating point, the link below explains an 8.8 method but it is easily portable to 16.16

http://zone.ni.com/devzone/conceptd.nsf/webmain/3AFBFF5DC5EE63E68625712C00604463

For now, I have pretty much given up on this problem as the encoding scheme you chose is fundamentally flawed and the problem is unsolvable in any consistent manner.

Donkey
Posted on 2006-06-11 15:38:45 by donkey
If you are interested in "standard" fixed point math, you could also have a look at the following (on the same site as the the other link I posted above):

http://www.ray.masmcode.com/fixmath.html

Or, to solve your problem, you could also use the FPULIB library. For example, if you want to load a constant real number on the FPU without declaring it in your data section, you could make the following call (MASM syntax) for a value of 3.25:

invoke FpuDiv,325,100,0,SRC1_DIMM or SRC2_DIMM or DEST_FPU


If you insist on using a "non-standard" fixed point system such as you proposed, you could convert it to an integer according to your system design and do the same as above. Using your original example of 00010005h in memory and knowing that the content of the low-word is strictly a fraction of 10 and the high-word is always positive, you could proceed as follows:

   mov  eax,myvar
  movzx edx,ax
  shr  eax,16
  imul eax,10
  add  eax,edx
  invoke FpuDiv,eax,10,0,SRC1_DIMM or SRC2_DIMM or DEST_FPU


The above would load the 00010005h as 1.5 on the FPU. However, if you should have something like 000A0011h in memory, the above code would load 11.7 on the FPU!!!!! :sad:

There are many ways to "skin a cat" but you MUST know what you are doing.  :) :) :)

Raymond
Posted on 2006-06-11 22:58:32 by Raymond