information loss from long to float in Java [duplicate]

╄→尐↘猪︶ㄣ 提交于 2020-01-30 03:27:29

问题


if you call the following method of Java

void processIt(long a) {
  float b = a;  /*do I have loss here*/
}

do I have information loss when I assign the long variable to the float variable?

The Java language Specification says that the float type is a supertype of long.


回答1:


Yes, this is possible: if only for the reason that float has too few (typically 6-7) significant digits to deal with all possible numbers that long can represent (19 significant digits). This is in part due to the fact that float has only 32 bits of storage, and long has 64 (the other part is float's storage format ). As per the JLS:

A widening conversion of an int or a long value to float, or of a long value to double, may result in loss of precision - that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).

By example:

long i = 1000000001; // 10 significant digits
float f = i;
System.out.printf(" %d %n %.1f", i, f);

This prints (with the difference highlighted):

 1000000001
 1000000000.0
          ~  ← lost the number 1

It is worth noting this is also the case with int to float and long to double (as per that quote). In fact the only integer → floating point conversion that won't lose precision is int to double.

~~~~~~

I say in part as this is also true for int widening to float which can also lose precision, despite both int and float having 32-bits. The same sample above but with int i has the same result as printed. This is unsurprising once you consider the way that float is structured; it uses some of the 32-bits to store the mantissa, or significand, so cannot represent all integer numbers in the same range as that of int.




回答2:


Do I have information loss when I assign the long variable to the float variable?

Potentially, yes. That should be fairly clear from the fact that long has 64 bits of information, whereas float has only 32.

More specifically, as float values get bigger, the gap between successive values becomes more than 1 - whereas with long, the gap between successive values is always 1.

As an example:

long x = 100000000L;
float f1 = (float) x;
float f2 = (float) (x + 1);
System.out.println(f1 == f2); // true

In other words, two different long values have the same nearest representation in float.

This isn't just true of float though - it can happen with double too. In that case the numbers have to be bigger (as double has more precision) but it's still potentially lossy.

Again, it's reasonably easy to see that it has to be lossy - even though both long and double are represented in 64 bits, there are obviously double values which can't be represented as long values (trivially, 0.5 is one such) which means there must be some long values which aren't exactly representable as double values.




回答3:


Yes you will, for example...

public static void main(String[] args) {
    long g = 2;
    g <<= 48;
    g++;

    System.out.println(g);
    float f = (float) g;
    System.out.println(f);
    long a = (long) f;
    System.out.println(a);
}

... prints...

562949953421313
5.6294995E14
562949953421312


来源:https://stackoverflow.com/questions/28304565/information-loss-from-long-to-float-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!