以下是代码段。
请使用小内存区域告诉使用这种保存大数据的算法。
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);
}
答案 0 :(得分:2)
答案是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标准表示。
答案 1 :(得分:1)
这里的关键点是数字的精度。 standard IEEE representation中的32位浮点数可能需要非常大且非常小的值:
±1.18×10-38至±3.4×1038
精度:约7位小数
通过将数字拆分为尾数和 exponent 来表示这些大小数字。尾数是存储“实际数字”的部分(而指数只存储“数字有多大”。而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位表示。
答案 2 :(得分:0)
尝试运行此代码:
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(和double)可以存储任何值(甚至是无穷大)但值越大,保存得越精确,因为它确实保留在有限的空间内
例如尝试:
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