News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

FPU compare real to integer problem

Started by RuiLoureiro, March 17, 2012, 01:36:34 PM

Previous topic - Next topic

RuiLoureiro

Hi all,
        Im working with FPU.
        I have a real10 number for exemple Num1=4.0000000 in 80 bit format
        This number is 4 but in real10 format.
       
        If i truncate it to an integer number i get Num2=4 in dword format.
        ;
        So i have one real10 number Num1=4.0000000 in 80 bit format (it is 4)
        and an integer number Num2=4 in dword format
;.........
    Num1    dt ???
    Num2    dd ???
;.........
        Now i want to compare Num1 with Num2 but i never get Num1 equal Num2
        and they are equal ! They are the same number: 4 !
       
        How to compare it corretly to get Num1 = Num2 ?
        Thanks


        Iam doing something like this:

        mov     eax, offset Num1
        fld     tbyte ptr [eax]
        mov     eax, offset Num2
        fild    dword ptr [eax]
        ...
        fcom
        ...

dedndave

hi Rui
you are trying to compare apples with oranges   :P
probably the best way is to convert the dword integer(s) to real10, then compare
the case for the value 4 is somewhat special because it is a power of 2, however
if you do the same thing for the value 5.0, the results will be different
that is because the value 5.0 in real10 form is not exactly 5.0 - it might be something like 4.999999999999999999

RuiLoureiro

Hi dave
        Ok !  :P
       
«probably the best way is to convert the dword integer(s) to real10»

Ok i have Num2=4 in dword format. Tell me what to do to convert it
to to real10. How to code it ?
thanks

qWord

hi RuiLoureiro,
your above code looks right. Probably you miss the point, that fcom does not set the flags.
It is recommended to use fcomi[p], which does this.

;compare a,b
f[i]ld b
f[i]ld a
fcomip st,st(1)
fstp st
;use je,ja,jb,jea,...
FPU in a trice: SmplMath
It's that simple!

dedndave

use FILD to load the integer into an FPU register
if you haven't already done so, i suggest you look over Ray's FPU tutorial   :U
http://www.ray.masmcode.com/tutorial/index.html
       fild    Num2
once it is loaded into the FPU, you can use one of the compare instructions (chapter 7)

to set up the FPU for 80-bit precision, you can just use FINIT
this also ensures that the 8 FPU registers are empty and available for use

dedndave

there have been a few recent discussions on this subject   :bg
you should be able to find all kinds of code, ideas, and theories - lol

http://www.masm32.com/board/index.php?topic=12998.0
http://www.masm32.com/board/index.php?topic=18253.0

MichaelW

I get equal for 4 or 5 (and for every other pair that I tried).

;==============================================================================
include \masm32\include\masm32rt.inc
.686
;==============================================================================

SHOWFLAGS MACRO
    push ebx
    pushfd
    pop ebx
    ;------------------------------------
    ; This from Raymond's fputute:
    ;                      ZF   PF   CF
    ; If ST(0) > ST(i)      0    0    0
    ; If ST(0) < ST(i)      0    0    1
    ; If ST(0) = ST(i)      1    0    0
    ; If ST(0) ? ST(i)      1    1    1
    ;------------------------------------
    .IF ebx & 64
        printf("1 ")
    .ELSE
        printf("0 ")
    .ENDIF
    .IF ebx & 4
        printf("1 ")
    .ELSE
        printf("0 ")
    .ENDIF
    .IF ebx & 1
        printf("1\n\n")
    .ELSE
        printf("0\n\n")
    .ENDIF
    pop ebx
ENDM

;==============================================================================
.data
    n1 REAL10 4.0
    n2 dd     4
    n3 REAL10 5.0
    n4 dd     5
.code
;==============================================================================
start:
;==============================================================================

    fld n1
    fild n2
    fcomip st(0),st(1)
    fstp st(0)
    SHOWFLAGS
    fld n3
    fild n4
    fcomip st(0),st(1)
    fstp st(0)
    SHOWFLAGS   

    inkey
    exit
;==============================================================================
end start
eschew obfuscation

dedndave

yah - the assembler assigns the same value to the float as the FPU does with FILD   :bg
but - if it is the result of some previous calculation, things can get a little difficult
comparing floats is no simple subject - refer to the threads i posted above

RuiLoureiro

qWord,
        Thanks

        I get this at instuction fcomip st,st(1) :
       
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

Assembling: ... : error A2085: instruction or register
not accepted in current CPU mode
_
Assembly Error
Prima qualquer tecla para continuar . . .

What to say ?


qWord

FPU in a trice: SmplMath
It's that simple!

jj2007

Run it with Olly, and watch what the FPU does. Or use MasmBasic's Fcmp macro.

MichaelW

There is more to be tested here than just the FPU comparisons. One possibility for the values not comparing as equal would be if MASM were not encoding the FP values correctly.
eschew obfuscation

RuiLoureiro

i returned to my work just now

qWord,
        Thanks it works

JJ2007,
        I dont want to test it

MichaelW,
        Thanks
       
        «There is more to be tested here than just the FPU comparisons.
        One possibility for the values not comparing as equal would be if MASM
        were not encoding the FP values correctly.»

        This is not a MASM problem.  :green2

    my problem:
   
        I type some numbers (2 and (2 and 2)). Each 2 is coded
        in real10. And we calculate 2^2 as a real10 number.
        I get 4 in real10. Nothing wrong.
       
        Now i need to calculate 2^4. 2 is real10, 4 is real10
        But i want to calculate this 2^4 like 2 in real10 and
        i want to get 4 in integer32 to use another formula.

        i think i could truncate the real10 4 to integer32
        but only if the real10 4 is equal to integer32 4.

        I get integer32 4 is greater than real10 4.

        May be i cannot do this this way !
        Any help ?
;------------------------------
        I have one formula to compute X^Y if X and Y are both real10
        and i have another formula to compute X^Y if X is real10
        and Y is integer32.
        But i dont want to code Y in integer32, this is the problem
        Did you understand the problem ?
;------------------------------

jj2007

Quote from: RuiLoureiro on March 17, 2012, 06:45:56 PM
        I dont want to test it

You don't have to. But you will never understand what your code does if you don't learn at least to use Olly.

Quote from: RuiLoureiro on March 17, 2012, 06:45:56 PM
        Now i need to calculate 2^4. 2 is real10, 4 is real10
        But i want to calculate this 2^4 like 2 in real10 and
        i want to get 4 in integer32 to use another formula.

        i think i could truncate the real10 4 to integer32
        but only if the real10 4 is equal to integer32 4.

        I get integer32 4 is greater than real10 4.

Do us a favour and read Ray's tutes.

dedndave

well - you may be able to do it entirely with integers   :P
how large can the numbers be ?

http://www.masm32.com/board/index.php?topic=12363.msg100575#msg100575