在Java中,长值如何在不损失精度的情况下适合浮点数据类型
在Java中,长值如何适应浮点数据类型而不损失精度。因为如果丢失了精度,那么应该生成以下代码段在Java中,长值如何在不损失精度的情况下适合浮点数据类型,java,floating-point,precision,long-integer,Java,Floating Point,Precision,Long Integer,在Java中,长值如何适应浮点数据类型而不损失精度。因为如果丢失了精度,那么应该生成以下代码段 long lMax = Long.MAX_VALUE; float f = lMax; System.out.println(lMax == f); Output true 问题是,对于long和float的比较,long值被转换为float,与赋值中发生的精度损失相同 如果要“检测”精度损失,请尝试使用BigDecimals,如下所示: System.out.println(new BigDe
long lMax = Long.MAX_VALUE;
float f = lMax;
System.out.println(lMax == f);
Output
true
问题是,对于
long
和float
的比较,long
值被转换为float
,与赋值中发生的精度损失相同
如果要“检测”精度损失,请尝试使用BigDecimal
s,如下所示:
System.out.println(new BigDecimal(lMax).compareTo(new Bigdecimal(f)));
我知道构造函数BigDecimal(double)
会将float
转换为double
,但不会丢失精度
编辑
对大多数人来说,long
似乎比float
更“精确”。然而,float
的范围是+/-10^38
,这比long
的范围大得多
测验
产出:
true
-1
true
true
9223372036854775807, 9223372036854775807
true
-1
false
true
9223372036854775807, 9223372036854775806
lMax的值=9223372036854775807;//在JVM中可能会有所不同 f值=9.223372E18 现在,当您比较
lMax==f
时,首先将f转换为long,然后进行比较。转换为long后,f值与lMax相同
同样的情况也适用于以下代码
long lMax = Long.MAX_VALUE; // value is 9223372036854775807
float f =lMax;
float f2 = 9223372036854775807.5f;
System.out.println(lMax == f);
System.out.println(lMax == f2);
输出
true
true
这里,与long相比,f2失去了十进制值。f2的长值与lMax相同。lMax是一个长数。将其指定为浮点值时,将失去精度 浮点数f=lMax 将long与float进行比较时,在内部,long转换为float,或者float转换为long。你的代码 lMax==f 将类似于 ((Float)f).longValue()==lMax 这是9.223372E18==9.223372E18 true 或 ((长)lMax).floatValue()==f 这是9223372036854775807==9223372036854775807 true 无论哪种方式,答案都是正确的。Java语言规范中的规则是理解问题中代码片段行为的关键。特别是“否则,如果其中一个操作数的类型为float,则另一个操作数将转换为float。”
在
lMax==f
比较中,lMax被转换为float,与float f=lMax
赋值完全相同。如果您使用相同的输入值,请对其执行两次相同的转换,并比较结果,无论转换是否更改了值,结果都是相等的。如果您想很好地演示精度损失,请在获取系统时间(毫秒)并从长时间转换为浮点时间时尝试以下小脚本:
class Scratch {
public static void main(String[] args) throws InterruptedException {
float currentF;
long currentL;
float lastNewF = 0;
long lastL = System.currentTimeMillis();
long diff;
while (true) {
currentL = System.currentTimeMillis();
currentF = (float) currentL;
if (currentF != lastNewF) {
// we finally got a new "different" float value
lastNewF = currentF;
diff = currentL - lastL;
lastL = currentL;
System.out.println(diff + " milliseconds since we got a new time as float");
}
Thread.sleep(250);
}
}
}
从输出中可以看出,有时会损失高达2分钟的精度:
0 milliseconds since we got a new time as float
46964 milliseconds since we got a new time as float
131054 milliseconds since we got a new time as float
131093 milliseconds since we got a new time as float
131077 milliseconds since we got a new time as float
如果
f
丢失精度,将其转换回long
将导致不同的long
值,并且可以看到丢失的精度。。。(一般来说,不是关于Long.MAX_VALUE
…)不,它将给出相同的结果。检查一下,我很关心这个问题。总的来说,您所说的是正确的。Long.MAX_值-1
给出了false
。。。。(System.out.printf(“%d,%d%n”,((Float)f.longValue(),lMax);
输出:9223372036854775807,9223372036854775806
)是的,没错。但在这里,他处理的是Long.MAX\u值。这就是我为什么这么说的原因。这是另一种方式。浮点值被转换为long。浮动f2=9223372036854775807.5f;System.out.println(lMax==f2);甚至这也会变成现实。见下面我的答案。
0 milliseconds since we got a new time as float
46964 milliseconds since we got a new time as float
131054 milliseconds since we got a new time as float
131093 milliseconds since we got a new time as float
131077 milliseconds since we got a new time as float