I am in a situation where I will have a lot of numbers around about 0 - 15. The vast majority are whole numbers, but very few will have decimal values. All of the ones with decimal value will be "#.5", so 1.5, 2.5, 3.5, etc. but never 1.1, 3.67, etc.
I'm torn between using float
and int
(with the value multiplied by 2 so the decimal is gone) to store these numbers.
Because every value will be .5, can I safely use float
without worrying about the wierdness that comes along with floating point numbers ? Or do I need to use int
? If I do use int
, can every smallish number be divided by 2 to safely give the absolute correct float
?
Is there a better way I am missing?
I'm not considering double
because I don't need that kind of precision or range.
I'm storing these in a wrapper class, if I go with int
whenever I need to get the value I am going to be returning the int
cast as a float
divided by 2.
What I went with in the end
float
seems to be the way to go.
This is not a theoretical proof but you can test it empirically:
public static void main(String[] args) {
BigDecimal half = new BigDecimal("0.5");
for (int i = 0; i < Integer.MAX_VALUE; i++) {
float f = i + 0.5f;
if (new BigDecimal(f).compareTo(new BigDecimal(i).add(half)) != 0) {
System.out.println(new BigDecimal(i).add(half) + " => " + new BigDecimal(f));
break;
}
}
}
prints:
8388608.5 => 8388608
Meaning that all xxx.5 can be exactly represented as a float between 0.5 and 8388607.5.
For larger numbers float's precision is not enough to represent the number and it is rounded to something else.
Let's refer to the subset of floating point numbers which have a decimal portion of .0 or .5 as point-five floats, or PFFs.
The following properties are guaranteed:
These properties are guaranteed by the IEEE-754 rules, which give a 24-bit mantissa and guarantee exact rounding of exact results.
Using int
s will give you a somewhat larger range.
There will be no accuracy issues with .5's with float for that range, so both approaches will work.
If these represent actual number values, I would chose the float simply because it consumes the same amount of memory and I don't need to write code to convert between some internal int representation and the exposed float value.
If these numbers represent something other than a value, eg a grade from a very limited set, I would consider modelling them as an enum, depending on how these are ultimately used.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.