hey all again

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

i did this :

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

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

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

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

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?

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?

but how would i make a compost value from a dword ?

im trying :

but i dont know for what value should i divide ( fdiv ) : 10f.. 100f so i can make the decimal part from it...

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...

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?

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?

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

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

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

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:

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:

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

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