繁体   English   中英

float(具有4个字节的内存)可以在Java中保持long(具有8个字节的内存)值。 怎么样?

[英]float (which is having 4bytes of memory) can hold long (which is having 8bytes of memory) value in Java. how?

这是代码片段。

请告诉我们使用哪种算法使用较小的存储区来保存大数据。

public static void main(String[] args) {
    long longValue = 2147483649L;//which is 8bytes in memory
    float floatValue = 23f;//which is 4bytes in memory
    floatValue = longValue;
    System.out.println(floatValue);
}

答案是float可以容纳一些 long值。 如果它可以适合float浮点表示。 其他人将失去精度或将转换为其他数字。

请参阅以下示例:

long l = Integer.MAX_VALUE;
System.out.println(l); // Prints 2147483647

float f = l;
System.out.printf("%f", f); // Prints 2147483648.000000

如您所见,将2147483647转换为float丢失的顺序(成为“不同”数字)。 即使“测试”数字明显适合4个字节(即使使用带符号表示),也不能适合4字节float表示(它也使用一些位,例如用于指数)。

浮点数使用IEEE 754标准表示。

这里的关键是数字的精度 标准IEEE表示形式中的 32位浮点数可以采用非常大和非常小的值:

±1.18×10−38至±3.4×1038
精度:约 7位十进制数字

通过将数字分为尾数指数来表示这些大数字和小数字。 尾数是存储“实际数”的部分(而指数仅存储“多少”。而32位浮点值的尾数有23位。

这意味着当您的long值变得太大(即大于可以用23位表示的值)时,两个不同的 long值将转换为相同的float值。

可以使用以下程序来快速(令人信服地)检查该问题:

public class LongAsFloat
{
    public static void main(String[] args)
    {
        float previousFloatValue = 0;
        for (long i=1; i<Long.MAX_VALUE; i++)
        {
            float floatValue = i;

            if (floatValue == previousFloatValue)
            {
                System.out.println("Got "+floatValue+" for "+i+" and "+(i-1));
                break;
            }
            previousFloatValue = floatValue;
            if (i % 10000L == 0)
            {
                System.out.println("Checking "+i);
            }
        }
    }
}

最终会打印

Got 1.6777216E7 for 16777217 and 16777216

并非巧合的是2 24 = 16777216-太大而无法用23位表示。

尝试运行以下代码:

    long longValue = Long.MIN_VALUE + 1; // which is 8bytes in memory
    float floatValue = longValue; // which is 4bytes in memory
    System.out.println(longValue + " != " + (long) floatValue);

它将打印: -9223372036854775807 != -9223372036854775808

浮点数(和双精度数)可以存储任何值 (甚至是无穷大),但该值变得越大,则保留的精度就越低,因为它确实保留在有限的空间中。

例如,尝试:

    float floatValue = (float) 9999999999999999999999999999999999999999999999999999999.9;
    System.out.println(floatValue);

它将打印Infinity

或这个:

    float floatValue = (float)   9999999999999999999999999999990d;
    float floatValue2 = (float) 10000000000000000000000000000000d;
    System.out.println(floatValue + " = " + floatValue2);

将打印:

1.0E31 = 1.0E31

暂无
暂无

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

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