Jump to content

Reminder: Int() and Floor() differ


jchd
 Share

Recommended Posts

This is to make users aware that both functions don't behave exactly the same: their rounding trigger point at a given value in ℝ often differ.

Local $n
$n = 0.99999999999999883429900999
ConsoleWrite(Int($n) & @LF)
$n = 0.99999999999999883429901
ConsoleWrite(Int($n) & @LF)
$n = 0.99999999999999994449919099
ConsoleWrite(Floor($n) & @LF)
$n = 0.999999999999999944499191
ConsoleWrite(Floor($n) & @LF)

I'm not saying there is a bug there, just that what one function regards as "the integral part of a floating-point value" is not always the same for the other function.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

I wonder how many times you had to run the code to get exact values. jchd, you're gonna break something :P

Yes, rounding algos for those functions are different. Still, that's not exactly what makes the difference. The difference is number called "error tolerance" for Int().

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

"error tolerance" for Int()

Never seen that term. OTOH I admit it's been ages since I last hardcoded FP in asm (and I don't miss that time!). There have been so many additions to the various FP architectures that it makes it hard to follow until you dig in compiler/library FP code.

I guess you mean the difference between "round toward ±∞" and "truncate" rounding control settings. I also believe the difference is not a fixed value and highly depends on where we are in the reals.

The first thing to remember is that it's quite possible that Int() and Floor() outputs differ by 1 on exceptional FP values very close to integers. The next point is that conversion from a litteral FP value in the source doesn't always result in the exact same value in the FP unit and printing back this double gives yet another value, as shown here:

Local $n
$n = 0.99999999999999883429900999
ConsoleWrite(StringFormat("n   = %040.38f\n1-n = %040.38f\n", $n, 1 - $n))
ConsoleWrite(Int($n) & @LF)
$n = 0.99999999999999883429901
ConsoleWrite(StringFormat("n   = %040.38f\n1-n = %040.38f\n", $n, 1 - $n))
ConsoleWrite(Int($n) & @LF)
$n = 0.99999999999999994449919099
ConsoleWrite(StringFormat("n   = %040.38f\n1-n = %040.38f\n", $n, 1 - $n))
ConsoleWrite(Floor($n) & @LF)
$n = 0.999999999999999944499191
ConsoleWrite(StringFormat("n   = %040.38f\n1-n = %040.38f\n", $n, 1 - $n))
ConsoleWrite(Floor($n) & @LF)

That only means that providing that many digits isn't meaningful and reliable. Binary FP is inherently imprecise.

I hit the Int() vs. Floor() difference the other day while playing with my own JulianDate() fractional seconds vs. some other application.

And BTW, I often date with Mia, a nice Italian girl whose name is Diccoto if I remind well. Mia and I do things in tight loops and I confess this always ends with premature termination. Nothing for you to be jealous of.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

I think this is due to the precision of (double) floating point variables, not int?

And in your tests you are using different numbers on floor() and int() comparisons, is that intentional?

 

Type Sign Exponent Significand field Total bits   Exponent bias Bits precision Number of decimal digits

Half (IEEE 754-2008) 1 5 10 16   15 11 ~3.3

Single 1 8 23 32   127 24 ~7.2

Double 1 11 52 64   1023 53 ~15.9

x86 extended precision 1 15 64 80   16383 64 ~19.2

Quad 1 15 112 128   16383 113 ~34.0

http://en.wikipedia.org/wiki/Floating_point

Edit, that table did not show as it did in the editor..

Edited by Geir1983
Link to comment
Share on other sites

 

I think this is due to the precision of (double) floating point variables, not int?

Yes.

 

And in your tests you are using different numbers on floor() and int() comparisons, is that intentional?

Yes, that's the purpose. This shows the distinct behavior (trigger point at 1-) between Int() and Floor().

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

That's why I posted that as a reminder so that some day a forum search could turn it up.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Local $n
$n = 0.99999999999999883429900999
ConsoleWrite(StringFormat("n   = %040.38f\n1-n = %040.38f\n", $n, 1 - $n))
ConsoleWrite(Int($n) & @LF)
$n = 0.99999999999999883429901
ConsoleWrite(StringFormat("n   = %040.38f\n1-n = %040.38f\n", $n, 1 - $n))
ConsoleWrite(Int($n) & @LF)
$n = 0.99999999999999994449919099
ConsoleWrite(StringFormat("n   = %040.38f\n1-n = %040.38f\n", $n, 1 - $n))
ConsoleWrite(Floor($n) & @LF)
$n = 0.999999999999999944499191
ConsoleWrite(StringFormat("n   = %040.38f\n1-n = %040.38f\n", $n, 1 - $n))
ConsoleWrite(Floor($n) & @LF)
That only means that providing that many digits isn't meaningful and reliable. Binary FP is inherently imprecise.

You do realize that in line of AutoIt code that goes like this:

$n = 0.99999999999999883429900999
...there are no actual numbers. It's just string which is at one point converted to DPFP number. Can string representation of number be always correctly converted to double? Would you expect amount of tolerance present?

One could argue that $n is not guarantied to have the value specified on the right. At that point any further comparisons or evaluations can't be used as proof of anything. Wouldn't you agree with that one?

And BTW, I often date with Mia, a nice Italian girl whose name is Diccoto if I remind well. Mia and I do things in tight loops and I confess this always ends with premature termination. Nothing for you to be jealous of.

Excellent, god luck with that. May the force be with you.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

You do realize that in line of AutoIt code that goes like this: ...

Yes of course, and my comment just points that out.

It's just string which is at one point converted to DPFP number.

That's the first untold point: these literals have to go thru (today's fashionable version of) strtod. The first value and the second one both exceed DP precision, yet convert to distinct values that cause a difference of 1 under Int(). Same for the third and fourth values under Floor().

I'm too lazy right now to dump the actual values with Hex() and add aegyptian fractions of powers of 2, but the first point is that there are indeed two distinct FP values that trigger Int() to return 0 and 1. Same for 3rd and 4th values which trigger Floor() to return 0 and 1.

These values are lower and upper literals which are triggering points for Int() and Floor() at the point 1- on the real scale. These triggering points can be reached in the middle of a computation, by yet another set of values in FP registers.

So my second point is that those lower and upper values are not the same for Int() and Floor(). This isn't unexpected but might bite someone someday.

 One could argue that $n is not guarantied to have the value specified on the right. At that point any further comparisons or evaluations can't be used as proof of anything.

I don't agree with the final sentence. Albeit $n clearly doesn't hold internally the values specified by the literals down to that excessive precision, that's true and again not surprising.

Yet, the values that finally get stored in FP registers are not the same. That it is for lower vs. upper bounds and for Int() and Floor().

Of course I'm also well aware that the converse conversion (?) from FP register to string thru StringFormat is only an approximation as well and I don't seriously expect the string ouput to reflect the actual FP value hold in the FPU register.

One last note: despite repeated improvements in the FP instruction set of various processors in the PC domain over decades, we're still stuck to the least common denominator for most applications which need to deliver consistent results across platforms. For instance I run a (slow) AMD Phenom which has a 128-bit FPU, yet 99.9999% of all FP computations rely on early FP instruction set, except (maybe) for programs like games and such which don't have to be reproductible exactly on someone else' machine. From this point of view super-advanced instruction sets are more "marketing hype translated in silicon" that something actually useful to the masses, barring rare exceptions.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

It's very hard and risky to publish software that's compiled to use new(er) instruction set because software companies have hard time working together with hardware companies. Their policies and visions are different. Microsoft, for example, had to start manufacturing their own hardware before compiling kernel to use new instructions.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

For extra FP stuff it can be done only for large applications which can afford detection of the underlying hardware and load the appropriate DLL for speedup reasons. But when you and me expect reproduceablility accross platforms extra precision is more error-prone than beneficial since the final results have to get converted according to the lowest denominator, which in practice is pretty old.

I guess you refer to recent SSEx, only there to speedup internal routines dramatically. High-end servers, kernels are first candidates, but laymen PCs running stock apps don't use that (AFAIK) except maybe for some multi-media renderers and some drivers. In these cases we don't need reults to be reproductible across machines, it's just that one PC displays more fps than others or similar advantage. Chipsets capabilities and various motherboard architectures complicate the situation ad nauseam.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...