This seems like a real simple question but I just to want clear my doubt. I am looking at code which some other developer wrote. There are some calculations involving floating-point numbers.
Example: Float fNotAvlbl = new Float(-99);
Why is he creating a new object? What would happen if we do Float fNotAvlbl = -99;
(-99 is used as flag here to indicate Not Applicable) Later down the code, we define:
fltValue1 = 0.00f;
fltValue2 = 0.00f;
and populate these two values with a method call whi开发者_如何学Goch returns float. After that we again convert these two values into Float Objects with:
fltVal1 = new Float(fltValue1);
fltVal2 = new Float(fltValue2);
and than do a comparison if(fltVal1.compareTo(fNotAvailable) == 0) do something.
I apologize if this is a real basic question.
- Writing
Float fNotAvlbl = -99;
relies on autoboxing, which has only been added in Java 5, so older code could not use it. - Using
-99
as a Float value to mean "Not Applicable" is really, really bad. Either usenull
orFloat.Nan
fltVal1.compareTo(fNotAvailable) == 0
means exactly the same asfltValue1==fltValue2
- Comparing float values for strict equality should not be done because it will often fail to work as expected. Read The Float-Point Guide to understand why.
- You don't need the wrappers at all
- Even if you needed them, using the constructor is not preferred - use
Float.valueOf(..)
instead.
On the subject of what compareTo()
does compared with ==
float a = Float.NaN;
float b = Float.NaN;
System.out.println(a + " == " + b + " is " + (a == b));
System.out.println(a + ".compareTo(" + b + ") is " + ((Float) a).compareTo(b));
float c = -0.0f;
float d = 0.0f;
System.out.println(c + " == " + d + " is " + (c == d));
System.out.println(c + ".compareTo(" + d + ") is " + ((Float) c).compareTo(d));
prints
NaN == NaN is false
NaN.compareTo(NaN) is 0
-0.0 == 0.0 is true
-0.0.compareTo(0.0) is -1
compareTo compares the binary representation (after normalising all NaN values to be the same) As the binary representation for -0.0f and 0.0f are different compareTo does not return 0. There is no special handling in the code other that to use floatToIntBits()
and compare that instea dof using ==
The comparison may be using the Float
object rather than the built-in float
type because of the inherent issues with floating point comparison. Because of the way that floating point numbers are stored on a computer system occasionally the equality comparison between two floating point numbers throws up false negatives. The compareTo
from Float
may take this into account. The original author possibly at least thought it did.
You can also write your own floating point comparison algorithm that checks for a difference within a reasonable standard deviation for your system. You can also use the method used by equals in Float, which looks at the integer value of the floating point bits for each number.
Note that using Float in and of itself doesn't fix this problem, as the problem is a round-off error in storage.
精彩评论