int或float表示只能是整数或"#。5"

时间:2015-09-11 15:11:01

标签: java floating-point int

情况

我的情况是,我会在0到15左右有很多数字。绝大多数都是整数,但很少有十进制值。所有带十进制值的都是"#。5",所以1.5,2.5,3.5等等,但从不1.1,3.67等。

我在使用floatint(值乘以2以便小数点消失)之间徘徊,以存储这些数字。

问题

因为的每个值都是.5,我是否可以安全地使用float而无需担心the wierdness that comes along with floating point numbers?或者我需要使用int吗?如果我使用int,可以将每个小数字除以2以安全地给出绝对正确的float吗?

我错过了更好的方法吗?

其他信息

我没有考虑double,因为我不需要那种精确度或范围。

我将这些存储在包装器类中,如果我在需要获取值的情况下使用int,我将返回int强制转换{{1}除以2。

  

我最终选择了什么

     

float似乎是要走的路。

3 个答案:

答案 0 :(得分:2)

这不是理论证明,但你可以凭经验进行测试:

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;
    }
  }
}

打印:

  

8388608.5 =&gt; 8388608

意味着所有xxx.5都可以精确地表示为介于0.5和8388607.5之间的浮点数。

对于较大的数字,浮点数的精度不足以表示数字,而是四舍五入到其他数字。

答案 1 :(得分:2)

让我们引用浮点数的子集,其小数部分为.0或.5作为五点浮点数或PFF。

保证以下属性:

  • 以.0或.5结尾的任何数字最多为800万左右(确切地说是2 ^ 23)可以表示为PFF。
  • 添加/减去两个PFF会产生PFF,除非出现溢出。
  • 将PFF乘以整数会产生PFF,除非出现溢出。

这些属性由IEEE-754规则保证,它提供24位尾数并保证精确舍入精确结果。

使用int s会给你一个更大的范围。

答案 2 :(得分:0)

对于该范围,浮点数不会出现精确度问题,因此两种方法都有效。

如果这些代表实际数字值,我会选择浮点数只是因为它消耗相同数量的内存而且我不需要编写代码来在一些内部int表示和暴露的浮点值之间进行转换。

如果这些数字代表某个值以外的其他数字,例如从一个非常有限的集合开始,我会考虑将它们建模为枚举,具体取决于最终如何使用它们。