Java implementation of Comparing floating point numbers
posted 8 years ago
This is more of an advanced numerical analysis question than about advanced Java....
In Comparison of Floating Point numbers
Bruce Dawson talks about how comparing floats and doubles is a lot harder than it looks.
He describes the problems, and provides some Clanguage code that does the comparison quickly and correctly.
java.lang.math.IEEEremainder() does something relative to this, but I can't follow exactly what from either the javadocs or chasing references to the real IEEE standad
In Comparison of Floating Point numbers
Bruce Dawson talks about how comparing floats and doubles is a lot harder than it looks.
He describes the problems, and provides some Clanguage code that does the comparison quickly and correctly.
java.lang.math.IEEEremainder() does something relative to this, but I can't follow exactly what from either the javadocs or chasing references to the real IEEE standad
Bill Shirley
Ranch Hand
Posts: 457
posted 8 years ago
Is there a question?
Yes, floating point representation in binary format is a very tricky computer science problem. Comparing floating point numbers is particularly tricky.
Since Java postdates IEEE 754, I assume is uses that standards comparison methods, but I don't rely on floats or doubles enough to ever bother.
Yes, floating point representation in binary format is a very tricky computer science problem. Comparing floating point numbers is particularly tricky.
Since Java postdates IEEE 754, I assume is uses that standards comparison methods, but I don't rely on floats or doubles enough to ever bother.
Bill Shirley  bshirley  frazerbilt.com
if (Posts < 30) you.read( JavaRanchFAQ);
posted 8 years ago
Well, there's java.lang.Float.intBitToFloat() and floatToIntBits() and friends; there are analagous methods in the Double class too. These should help satisfy your curiosity, if nothing else.
Originally posted by Pat Farrell:
The tricks he uses are only applicable for C, they rely upon pointers and using the same location in memory as both a float and an int. Not possible in Java
Well, there's java.lang.Float.intBitToFloat() and floatToIntBits() and friends; there are analagous methods in the Double class too. These should help satisfy your curiosity, if nothing else.
posted 8 years ago
Thanks. I'm more than curious, I'm looking for a good implementation. For suitable values of good.
Originally posted by Ernest FriedmanHill:
Well, there's java.lang.Float.intBitToFloat() and floatToIntBits() and friends; there are analagous methods in the Double class too. These should help satisfy your curiosity, if nothing else.
Thanks. I'm more than curious, I'm looking for a good implementation. For suitable values of good.
Nicholas Jordan
Ranch Hand
Posts: 1282
posted 8 years ago
Source: Floating point remainder in Kaffe
According to the JLS (S15.16.3) Java's floating point remainder (using the '%' operator) is *different from* the java.lang.Math.IEEEremainder()
function. The operator is based on truncating division while the
function is based on rounding division. You might think that this
won't add up to much, but 8.0 % 3.0 results in 1.0 with rounding
division versus 2.0 with truncating division.
Source: Floating point remainder in Kaffe
posted 8 years ago
Hi Pat,
OK, I went and looked at the (interesting) linked document. I think you could work from that pretty well, with the following translation: when they have
*(int*)&A
the Java equivalent would be
Float.floatToIntBits(A)
so his final comparison function would be
I did some minimal testing and this seems to work as advertised, but you should probably do more extensive testing.
OK, I went and looked at the (interesting) linked document. I think you could work from that pretty well, with the following translation: when they have
*(int*)&A
the Java equivalent would be
Float.floatToIntBits(A)
so his final comparison function would be
I did some minimal testing and this seems to work as advertised, but you should probably do more extensive testing.
posted 8 years ago
Originally posted by Ernest FriedmanHill:
I have done a bit of testing and I don't grok this line. The key, which I couldn't tell until I fired up some test cases and the debugger, is that this comparison is done on the difference of the "integer" values. I have no idea what scale is applicable, ideal, good.
consider these values: ( 0.1F, 0.10000001F)
on my system (intel x86 32 bits) I get a raw difference of 536870912
aka 536,870,912 or 500 million. This fails your assertion test.
I can see that the integer comparison style is a lot faster, but it looks a lot less understandable than the division based relative calculation that the paper says is not good (it has lots of floating abs() etc.
posted 8 years ago
I've put up some source files, and JUnit tests on my server for others who are interested.
Math java source, Complex, AboutEquals
Math java source, Complex, AboutEquals
posted 8 years ago
Hmmm. I don't know how that could be. The answer should be the same on every system, guaranteed by IEEE floatingpoint standard. On my system this difference is actually 1, which is as it should be.
"ulp" stands for "unit of least precision". A difference of one ulp between two floats indicates that they're "adjacent" floats; that there's no value in between them. If I were using this method I'd probably pass values between 1 and 5 most of the time.
There are ulp(float) and ulp(double) methods in java.lang.Math which show you the absolute magnitude of the difference between a float or double and its nearest neighbor; you should check these out. Based on what I saw here you should find that ulp(0.1) is roughly 0.00000001.
Originally posted by Pat Farrell:
consider these values: ( 0.1F, 0.10000001F)
on my system (intel x86 32 bits) I get a raw difference of 536870912
aka 536,870,912 or 500 million. This fails your assertion test.
Hmmm. I don't know how that could be. The answer should be the same on every system, guaranteed by IEEE floatingpoint standard. On my system this difference is actually 1, which is as it should be.
"ulp" stands for "unit of least precision". A difference of one ulp between two floats indicates that they're "adjacent" floats; that there's no value in between them. If I were using this method I'd probably pass values between 1 and 5 most of the time.
There are ulp(float) and ulp(double) methods in java.lang.Math which show you the absolute magnitude of the difference between a float or double and its nearest neighbor; you should check these out. Based on what I saw here you should find that ulp(0.1) is roughly 0.00000001.
posted 8 years ago
Which is one of the reasons I put the code up with URL above
Originally posted by Ernest FriedmanHill:
Hmmm. I don't know how that could be. The answer should be the same on every system, guaranteed by IEEE floatingpoint standard. On my system this difference is actually 1, which is as it should be.
Which is one of the reasons I put the code up with URL above
posted 7 years ago
Reviving an ancient thread since I'm doing more testing in it:
Checking the Math.ulp() functions shows that Dr FriedmanHill is right.
For floating: f: a: 0.100000, ulpA: 7.45058e09,
for double: d: a: 0.100000, ulpA: 1.38778e17,
and for more obscure values, testing one that is 10 ^ 41, which is very close to zero:
d: a: 1.00000e41, ulpA: 1.27447e57,
40 more orders of magnitude smaller:
d: a: 1.00000e81, ulpA: 1.17042e97,
Ernest FriedmanHill wrote:There are ulp(float) and ulp(double) methods in java.lang.Math which show you the absolute magnitude of the difference between a float or double and its nearest neighbor; you should check these out. Based on what I saw here you should find that ulp(0.1) is roughly 0.000 000 01.
Checking the Math.ulp() functions shows that Dr FriedmanHill is right.
For floating: f: a: 0.100000, ulpA: 7.45058e09,
for double: d: a: 0.100000, ulpA: 1.38778e17,
and for more obscure values, testing one that is 10 ^ 41, which is very close to zero:
d: a: 1.00000e41, ulpA: 1.27447e57,
40 more orders of magnitude smaller:
d: a: 1.00000e81, ulpA: 1.17042e97,
I RELEASE YOU! (for now .... ) Feel free to peruse this tiny ad:
the new thread boost feature: great for the advertiser and smooth for the coderanch user
https://coderanch.com/t/674455/ThreadBoostfeature
