The MASM Forum

General => The Campus => Topic started by: six_L on December 09, 2020, 06:41:50 PM

Title: Comparison of two floating point values
Post by: six_L on December 09, 2020, 06:41:50 PM
hello all
if this two floating point values are equal, then CRITERIA > | temp_var1 - temp_var2 |
so, in FCPU "jz   criteria_equal" never happens.
Do I understand correctly ?
.data
criteria dt 1.00e-12
temp_var1 dt 1.710000000003         
temp_var2 dt 1.710000000002       



Test_1 Proc
finit
fld temp_var1
fld temp_var2 ;load previous value => ST(0)=previous value, ST(1)=current value
fsub st,st(1) ;difference with current value
fabs ;get the absolute value of the difference
fld criteria ;load the criteria=> ST(0)=criteria, ST(1)=abs(difference), ST(2)=current value
fcompp ;compare the criteria to the difference and discard both values from the FPU => ST(0)=current value
fstsw ax ;retrieve comparison result in the AX register
fwait ;insure the previous instruction is completed
sahf ;transfer the condition codes to the CPU's flag register

;In this type of code, the computed values should already have been verified
;to be valid numbers. Their difference should thus be a valid number, as well
;as the criteria. Therefore no need to check for an indeterminate comparison.

ja criteria_greater ;criteria was ST(0) for comparison
jb criteria_lower
jz criteria_equal
criteria_greater:
mov rax,1
jmp @exit
criteria_lower:
mov rax,-1
jmp @exit
criteria_equal:
mov rax,0
@exit:
ret
Test_1 EndP
Title: Re: Comparison of two floating point values
Post by: jj2007 on December 09, 2020, 09:42:58 PM
There is a long thread in the old forum (http://fpu%20compare%20real%20to%20integer%20problem) (it led to the Fcmp macro (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1200)). Basically, the problem is that "equal" is a tough concept for floating point values. They rarely are equal, i.e. PI is not 3.141592653589793238:

include \masm32\MasmBasic\MasmBasic.inc
.data
MyPI REAL10 3.141592653589793238

  Init
  fldpi ; as precise as the hardware allows...
  Fcmp MyPI, ST(0), medium ; do a float comparison with medium precision
  .if Zero?
PrintLine "MyPI equals the real PI"
  .elseif FcmpLess
PrintLine "MyPI is below the real PI"
  .else
PrintLine "MyPI is below the real PI"
  .endif
  Fcmp MyPI, ST(0), top ; do a float comparison with top precision
  .if Zero?
PrintLine "MyPI equals the real PI"
  .elseif FcmpLess
PrintLine "MyPI is below the real PI"
  .else
PrintLine "MyPI is below the real PI"
  .endif
EndOfCode


Output:
MyPI equals the real PI
MyPI is below the real PI
Title: Re: Comparison of two floating point values
Post by: hutch-- on December 09, 2020, 10:05:45 PM
Just a suggestion that I have not tried in this context, how about doing it in SSE2 using,

comisd      ; compare two dbl values and set eflags (jz jnz je jne etc...)
Title: Re: Comparison of two floating point values
Post by: daydreamer on December 10, 2020, 04:22:36 AM
I have some similar problem with integers,causing oscillation,would be nice if someone had solution to this
its comparision between mouseclick x,y and object x,y moving to mouse x,y
cmp xy coordinates sets deltax and deltay +5 or -5 or 0 if lucky enough to find exact xy or I get into oscillating between two coordinates
Title: Re: Comparison of two floating point values
Post by: hutch-- on December 10, 2020, 04:27:03 AM
There is no point in using floating point with screen coordinates when their integer range is so small.
Title: Re: Comparison of two floating point values
Post by: jj2007 on December 10, 2020, 04:59:20 AM
Quote from: hutch-- on December 09, 2020, 10:05:45 PM
Just a suggestion that I have not tried in this context, how about doing it in SSE2 using,

comisd      ; compare two dbl values and set eflags (jz jnz je jne etc...)


You get equality only when all 64 bits are equal. Depending on your case, that can be ok or misleading.
Title: Re: Comparison of two floating point values
Post by: raymond on December 10, 2020, 05:40:02 AM
You must realize that you were feeding the computer some numbers in the decimal form. The FPU then has to convert them to their binary form.

Simply compare this to the conversion of exact integer fractions x/y to their decimal form z.zzzz, and lets use the simple 1/3, i.e. 0.3333333333.....

If you round it to 5 decimal digits, you would get 0.33333. If you do the same thing with its double, i.e. 2/3, you get 0.66667. Now, imagine dividing the latter by 2 and reporting it with 8 decimal digits, the result would be 0.33333500. If you then compare that result with 1/3 in the decimal form with 8 decimal digits, it definitely would not give you an equality result.

The example used in this thread converts decimal values to binary with 64 bits of accuracy. The 65th bit would have determined how its going to be rounded, and could mean the difference in close comparisons (specially that the decimal values provided in the example only show an accuracy of less than some 45 binary bits).
Title: Re: Comparison of two floating point values
Post by: six_L on December 10, 2020, 04:28:08 PM
thank you for providid this useful information .  :thumbsup:
Title: Re: Comparison of two floating point values
Post by: six_L on December 10, 2020, 05:30:30 PM
@daydreamer:
Quoteits comparision between mouseclick x,y and object x,y moving to mouse x,y
that's meaning to track the object. it requires:
1、Rapidity
2、Steadily
3、Accuracy
Generally, PID( Proportional Integral Derivative) is used. The PID algorithm is a little complicated. you'll search the relevant information about PID. 
Title: Re: Comparison of two floating point values
Post by: TouEnMasm on December 10, 2020, 08:14:50 PM
Quote
I have some similar problem with integers,causing oscillation,would be nice if someone had solution to this
its comparision between mouseclick x,y and object x,y moving to mouse x,y
cmp xy coordinates sets deltax and deltay +5 or -5 or 0 if lucky enough to find exact xy or I get into oscillating between two coordinates

The only error here is to use floating point numbers where integer numbers must be used.
Only Integers can give the exact value of a screen coordinate.
Floating point numbers have a precision beetween a lower and a upper value who made what you call an oscillation between two values of screen coordinate.
Use only integers and they will not have variations in the calculations.



Title: Re: Comparison of two floating point values
Post by: daydreamer on December 11, 2020, 05:12:33 AM
Thanks sixl,that formula origins are from old analog control system ways,using integers, it's more like thermostat binary on/off system, solution might be try 20 c degree turn off,while 18?c degree turns on? Add kind of conditional code if x<20 && x>18 xdelta=0
Smooth physics movement/calculations best with floats
floats and if using gdi only final conversion to int


Title: Re: Comparison of two floating point values
Post by: HSE on December 11, 2020, 05:30:03 AM
Quote from: daydreamer on December 10, 2020, 04:22:36 AM
or I get into oscillating between two coordinates
Then you have to make subpixel calculations around coordinates, and you are the expert in games here!  :thumbsup: