在Java中,float(内存为4字节)可以保存long(内存为8字节)值。怎样?
下面是代码片段 请告诉我,这种使用小内存区域保存大数据的算法是什么在Java中,float(内存为4字节)可以保存long(内存为8字节)值。怎样?,java,long-integer,Java,Long Integer,下面是代码片段 请告诉我,这种使用小内存区域保存大数据的算法是什么 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(floatVal
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
值。如果它适合于浮点
浮点表示形式。其他数字将失去精度或转换为不同的数字
请参见此示例:
long l = Integer.MAX_VALUE;
System.out.println(l); // Prints 2147483647
float f = l;
System.out.printf("%f", f); // Prints 2147483648.000000
如您所见,将2147483647转换为float
lost-precision(成为一个“不同”的数字)。尽管“测试”数字明显适合4字节(即使使用有符号表示),但它不能适合4字节浮点
表示(它还使用一些位,例如指数)
浮点数使用标准表示。请尝试运行以下代码:
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);
它将打印无限
或者这个:
float floatValue = (float) 9999999999999999999999999999990d;
float floatValue2 = (float) 10000000000000000000000000000000d;
System.out.println(floatValue + " = " + floatValue2);
将打印:
1.0E31 = 1.0E31
这里的关键是数字的精度。中的32位浮点数可以采用非常大和非常小的值:
±1.18×10−38至±3.4×1038精度:约7位小数 这些大的和小的数字通过将数字拆分为尾数和指数来表示。尾数是存储“实际数字”的部分(而指数只存储“数字有多大”。32位浮点值的尾数有23位 这意味着,当长值变得太大(即,大于可用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);
}
}
}
}
并非巧合,224=16777216-太大了,无法用23位表示。你可以给一个浮点赋值一个long,但你会失去精度这个问题有一个Java难题-它试图使用浮点循环,看,循环永远循环(因为跳过了数字,或者当
f+1==f
且浮点保持不变时效果更好)。
Got 1.6777216E7 for 16777217 and 16777216