hi folks

why is the fpu rounding my result ?

Result gives me 16

should be 15,966386554621848739495798319328

i only need 15,96

Can somebody explain what i doing wrong?

Kind Regards

jpam

why is the fpu rounding my result ?

Result gives me 16

should be 15,966386554621848739495798319328

i only need 15,96

Can somebody explain what i doing wrong?

Kind Regards

jpam

`local MyNumber:dword`

local Divider:dword

local Result:dword

mov , 1900

mov , 119

mov , 1900

mov , 119

FILD MyNumber

FILD Divider

FDIV

FIST Result

DbgDec Result

DbgFloat Result

Firstly, you're storing the result as a 32bit INTEGER, not a float.

So don't expect to make sense of DbgFloat output!

Secondly, you're not popping the value from ST(0), you left it there!

FIST = store result as integer, dont pop a value from the fpu stack

FISTP = store result as integer, DO pop a value from the fpu stack

FST = store as float, no pop

FSTP = store as float, with pop

Also : You can get more fpu accuracy by using REAL8 or REAL10 data types.

These are bigger yes, but easy to use.

eg

local Result:REAL8 (or REAL10) for floats

or

local Result:QWORD (or TWORD) for integers

As you noticed, you can specify dword in place of real4 (etc) without generating errors, masm wont care if the data types are the same size.

should be 15,966386554621848739495798319328

This is another detail you have to learn. The BEST you can expect from the FPU (with extended-double precision) is equivalent to approximately 19 digits in the decimal system. Thus don't expect to ever get anything more precise than:

15,96638655462184874

If you intend to continue using the FPU without too much stumbling, you can have a glance at the following if you are not yet aware of it:

http://www.ray.masmcode.com/tutorial/index.html

Don't panic! The learning curve is not very steep, it wasn't so long ago that I was in your position.

Feel free to ask questions, don't be put off by the tone of my previous response, we're here to help :)

You are starting exactly the right way, with simple fpu calculations, and with the benefit of runtime debug support.

Feel free to ask questions, don't be put off by the tone of my previous response, we're here to help :)

You are starting exactly the right way, with simple fpu calculations, and with the benefit of runtime debug support.

Thanks Homer & Raymond

i use the REAL4 now

the Result is now 1.596638679504E+0001

allmost good, but the decimal point should be after the 5, like 15.96638679504E+0001

The fpu tutorial was allready in my masm dir and is now my main study object :)

current code

i use the REAL4 now

the Result is now 1.596638679504E+0001

allmost good, but the decimal point should be after the 5, like 15.96638679504E+0001

The fpu tutorial was allready in my masm dir and is now my main study object :)

current code

`local MyNumber:REAL4`

local Divider:REAL4

local Result:REAL4

mov , 1900

mov , 119

FLD MyNumber

FLD Divider

FDIV

FSTP Result

DbgDec Result

DbgFloat Result

Looks OK to me: 1900 / 119 = ~15.9 = ~1.59E+1 It's called scientific notation. So your code is now correct :)

Yeah - the E+1 can be thought of as "shift the decimal point by +1 places", or "*10 ^1"

So 1.50 becomes 15.0

And it works similarly for negative values such as E-3 (ie /10 ^3, ie /1000)

For very big or very small numbers, it means we dont have to print a whole bunch of zeroes to express the value.

So 1.50 becomes 15.0

And it works similarly for negative values such as E-3 (ie /10 ^3, ie /1000)

For very big or very small numbers, it means we dont have to print a whole bunch of zeroes to express the value.

If the code is correct

how do i get rid of that E notation

i only want that my result outputs 15.96

???

how do i get rid of that E notation

i only want that my result outputs 15.96

???

The notation depends only on the tool you use to view the value. The binary form is 417F7652 (32-bit float which yields about 6 significant decimal digits -- see IEEE-754). It's up to you how you present it to the user. It can be 15.9663 or 1.59663E+1 or whatever.

Unfortunately, DbgFloat macro doesn't let you do that.

But you can do it yourself with a few more lines :)

Inside the DbgFloat macro is a call to a procedure called ST0ToStr.

; Arguments: Arg1: Pointer to destination buffer (at least 20 bytes + padding bytes).

; Arg2: Number of padding bytes.

; Arg3: Number of decimal places.

; Arg4: Format flag (f_NOR or f_SCI)

I doubt that Biterider will bother adding a Flags argument to the DbgFloat macro, but you never know ;)

BTW - DbgFloat already has 4 possible arguments, you should read the comments for DbgFloat (in Debug.inc)

But you can do it yourself with a few more lines :)

Inside the DbgFloat macro is a call to a procedure called ST0ToStr.

; Arguments: Arg1: Pointer to destination buffer (at least 20 bytes + padding bytes).

; Arg2: Number of padding bytes.

; Arg3: Number of decimal places.

; Arg4: Format flag (f_NOR or f_SCI)

local stringbuffer[256]:BYTE

local MyNumber:REAL4

local Divider:REAL4

local Result:REAL4

mov , 1900

mov , 119

FLD MyNumber

FLD Divider

FDIV

FST Result ;leaving it on the FPU in ST(0) as an input param to the following call

lea eax,stringbuffer ;we have to supply Pointer to buffer that receives output string

invoke St0ToStr, eax, 0, 15, f_NOR ;no padding, 15 places, normal notation

fUnload ;super secret OA32 macro for popping ST(0) from the fpu stack

DbgStr stringbuffer ;Display the string

I doubt that Biterider will bother adding a Flags argument to the DbgFloat macro, but you never know ;)

BTW - DbgFloat already has 4 possible arguments, you should read the comments for DbgFloat (in Debug.inc)

wow !

youre my hero Homer :)

only had to add % include &MacPath&fMath.inc for the f_NOR constant

and the fUnload command

next time i have to search deeper in those inc and lib files :)

many thanks Homer to show me how to use those commands !

Kind regards

jpam

youre my hero Homer :)

only had to add % include &MacPath&fMath.inc for the f_NOR constant

and the fUnload command

next time i have to search deeper in those inc and lib files :)

many thanks Homer to show me how to use those commands !

Kind regards

jpam

You can eliminate one instruction

FLD MyNumber ST(0) = MyNumber

FDIV Divider ST(0) = ST(0) / Divider , which is our result

FST Result ST(0) still contains the result

FLD MyNumber ST(0) = MyNumber

FDIV Divider ST(0) = ST(0) / Divider , which is our result

FST Result ST(0) still contains the result

jpam,

If the tutorial was already in your MASM32 folder, you should also have the Fpulib. It has a conversion function (FpuFLtoA) where you can specify the number of digits after the decimal delimiter, whether you want the result in regular or scientific notation, and how many leading blanks you need for alignment of the decimal delimiter. The only drawback is that, if the float is in memory, it needs to be in the REAL10 format (if it is in the top FPU register, it's already in REAL10 format).

If the tutorial was already in your MASM32 folder, you should also have the Fpulib. It has a conversion function (FpuFLtoA) where you can specify the number of digits after the decimal delimiter, whether you want the result in regular or scientific notation, and how many leading blanks you need for alignment of the decimal delimiter. The only drawback is that, if the float is in memory, it needs to be in the REAL10 format (if it is in the top FPU register, it's already in REAL10 format).

Thanks Raymond

i allready notice that function FpuFLtoA

and i saw alot other very nice functions :P

But Homer's solution is working perfect for me

i am trying alot different functions and fpu commands in my test app

just for learning purpose

Thanks for all the help guys

i allready notice that function FpuFLtoA

and i saw alot other very nice functions :P

But Homer's solution is working perfect for me

i am trying alot different functions and fpu commands in my test app

just for learning purpose

Thanks for all the help guys