简体   繁体   English

int或float表示只能是整数或“#.5”的数字

[英]int or float to represent numbers that can be only integer or “#.5”

Situation 情况

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. 我处于一种情况,我会在大约0到15之间有很多数字。绝大多数是整数,但是很少会有十进制值。 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. 所有带有十进制值的值都将是“#.5”,因此是1.5、2.5、3.5等,但绝不会是1.1、3.67等。

I'm torn between using float and int (with the value multiplied by 2 so the decimal is gone) to store these numbers. 我在使用floatint (值乘以2,所以小数点消失)之间float ,无法存储这些数字。

Question

Because every value will be .5, can I safely use float without worrying about the wierdness that comes along with floating point numbers ? 因为每个值是3.5,我可以放心地使用float ,而不必担心与浮点数走来的wierdness Or do I need to use int ? 还是我需要使用int If I do use int , can every smallish number be divided by 2 to safely give the absolute correct float ? 如果我使用int ,是否可以将每个float除以2以安全地给出绝对正确的float

Is there a better way I am missing? 有没有更好的方法我想念?

Other info 其他资讯

I'm not considering double because I don't need that kind of precision or range. 我没有考虑double因为我不需要那种精度或范围。

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. 我将它们存储在包装器类中,如果每当我需要获取值时都使用int ,则将返回的intfloat除以2。

What I went with in the end 最后我去了什么

float seems to be the way to go. float似乎是要走的路。

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 8388608.5 => 8388608

Meaning that all xxx.5 can be exactly represented as a float between 0.5 and 8388607.5. 意味着所有xxx.5都可以精确地表示为0.5到8388607.5之间的浮点数。

For larger numbers float's precision is not enough to represent the number and it is rounded to something else. 对于较大的数字,float的精度不足以表示该数字,并且将其四舍五入为其他值。

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. 让我们将小数部分为.0或.5的浮点数子集称为点五浮点数或PFF。

The following properties are guaranteed: 保证以下属性:

  • Any number up to 8 million or so (2^23, to be exact) which ends in .0 or .5 is representable as a PFF. 任何以.0或.5结尾的不超过800万左右(准确地说是2 ^ 23)的数字都可以表示为PFF。
  • Adding/subtracting two PFFs results in a PFF, unless there's overflow. 除非有溢出,否则将两个PFF相加/相减会得到一个PFF。
  • Multiplying a PFF by an integer results in a PFF, unless there's overflow. 除非有溢出,否则将PFF乘以整数会得到PFF。

These properties are guaranteed by the IEEE-754 rules, which give a 24-bit mantissa and guarantee exact rounding of exact results. 这些属性由IEEE-754规则保证,该规则给出24位尾数并保证精确结果的精确舍入。

Using int s will give you a somewhat larger range. 使用int会给您更大的范围。

There will be no accuracy issues with .5's with float for that range, so both approaches will work. 在该范围内,浮点数的.5不会有精度问题,因此这两种方法都可以使用。

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. 如果这些值代表实际的数字值,我之所以选择浮点数仅仅是因为它消耗了相同数量的内存,并且我不需要编写代码就可以在某些内部int表示形式和公开的浮点值之间进行转换。

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. 如果这些数字表示值以外的其他值,例如来自非常有限的等级,则我将考虑将它们建模为枚举,这取决于最终使用方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM