Author Topic: Comparing single variable fails.  (Read 1411 times)

0 Members and 1 Guest are viewing this topic.

Brian Alvarez

  • Guest
Comparing single variable fails.
« on: May 12, 2019, 11:26:38 AM »
This displays equals:

Code: [Select]
double p1 = 1.3

if p1 = 1.3 then
    print "equals!"
else
    print str(p1) " is not equal to " 1.3
end if

This displays is not equal:

Code: [Select]
single p1 = 1.3

if p1 = 1.3 then
    print "equals!"
else
    print str(p1) " is not equal to " 1.3
end if

Maybe comparing singles should have a small margin of error due to precision loss?

Charles Pegge

  • Guest
Re: Comparing single variable fails.
« Reply #1 on: May 12, 2019, 09:47:17 PM »
In most circumstances floating point-values should never be compared for equality. The airbus will eventually dive into the ground!

JRS

  • Guest
Re: Comparing single variable fails.
« Reply #2 on: May 13, 2019, 01:39:00 AM »
Hi Charles,

Does O2 have a FORMAT() like function to limit precision for floating point numbers?

Schoolboy Math

Mike Lobanovsky

  • Guest
Re: Comparing single variable fails.
« Reply #3 on: May 13, 2019, 11:20:31 AM »
John,

format() only limits the length of the string representation of a real value as generated by print() doing rounding as necessary but it doesn't affect the precision of maths in which the real is involved.

Brian,

Your example is ill strategically. Not all decimal fractions that a binary CPU has to deal with in real life can be represented by the CPU (or rather its FPU) with an exact and finite number of decimal places. It pertains to both single- and double-precision values. The "small margin of error" usually called epsilon should be used for real value comparison except against 0/0.f/0.d (those are guaranteed to be nil on all hardware platforms) to be on the safe side.

Thus, if p1 = 1.3 then should be replaced with if p1 - 1.3 < epsilon then, where epsilon depends on the field of science that your code targets. I usually use 0.001 in my OpenGL exercises; some other 3D developers may go down to 0.00001. Most modern C/C++ compilers will even warn you each time you attempt to generate an exact comparison statement like yours in your floating-point calc.

There's no such notion as equal in floating-point math; almost equal is the closest you'll ever get, except for zero as I already mentioned.

Brian Alvarez

  • Guest
Re: Comparing single variable fails.
« Reply #4 on: May 13, 2019, 04:54:16 PM »
 Mike, i am well aware of such issues, im used to precision loss, Java makes a good job at reminding me about such losses.

 My intention was also to point charles attention that *maybe* the internal comparison method could be temporarily storing the
literal into a double, making the "ill " comparison fail. This is because maybe it could have something to do with the issue i
posted in my other thread. If that was the case, maybe using a single temporary variable could fix all the issues in this case,
just like changing the data type of the other statement (to the data type that matches it) could fix it.

 In short what i mean, is... i know its not a good idea to compare floating point variables. But if you store one floating point number
into a specific data type variable... and you inmediately compare it to another exactly the same, and the comparison fails... something
must be off in the comparison. Something that could be fixed by using the same procedure to store the number and to compare it. maybe?

Charles Pegge

  • Guest
Re: Comparing single variable fails.
« Reply #5 on: May 14, 2019, 02:10:15 AM »
Hi John,

o2 does not have a buit-in format procedure but it can use C sprintf:

Code: [Select]
uses corewin
char c[32]
sprintf( c,"%0.3f", convert double pi() )
print c  '3.142

PS: The next update will correct the stack cleanup (using unprototyped sprintf with double params)

JRS

  • Guest
Re: Comparing single variable fails.
« Reply #6 on: May 14, 2019, 02:41:49 AM »
FORMAT in SB is more than  a PRINT output formater. The results limit precision for an expression.

Code: Script BASIC
  1. a = FORMAT("%0.1f",0.3) + FORMAT("%0.1f", 0.3) + FORMAT("%0.1f", 0.3)
  2.  

Charles Pegge

  • Guest
Re: Comparing single variable fails.
« Reply #7 on: May 14, 2019, 02:59:55 AM »
In o2 we would need to convert the formatted number-strings back to numbers witn val().


Perhaps the best solution to the problem is to explicitly test for approximate value:

Code: [Select]
function approx(float a,b,e) as int
===================================
'a first number
'b second number to compare with
'e error factor
e+=1
if (a<=b*e)and(a>=b/e)
  return 1
endif
end function

print approx( 1.2, 1.21, 0.01) '1
print approx( 1.2, 1.22, 0.01) '0

Mike Lobanovsky

  • Guest
Re: Comparing single variable fails.
« Reply #8 on: May 14, 2019, 03:14:27 PM »
Code: Script BASIC
  1. a = FORMAT("%0.1f",0.3) + FORMAT("%0.1f", 0.3) + FORMAT("%0.1f", 0.3)
  2.  

Then I wouldn't call it format in the first place. I'd rather call it round.

JRS

  • Guest
Re: Comparing single variable fails.
« Reply #9 on: May 14, 2019, 07:43:54 PM »
 ;D