机器精度

5

我正在寻找一种简单的方法来近似计算Java中的机器精度:

float machEps = 1.0f;

do
    machEps /= 2.0f;
while ((float) (1.0 + (machEps / 2.0)) != 1.0);

System.out.println( machEps);

这将返回:
1.1920929E-7

然而,当我在 while 循环中删除对 float 的转换时:

float machEps = 1.0f;

do
   machEps /= 2.0f;
while ( (1.0 + (machEps / 2.0)) != 1.0);

System.out.println( machEps);

I get:

2.220446E-16

我不太确定为什么会出现这种情况……我的猜测是在第二种情况下,Java试图将machEpsfloat扩展到double。但是,我不确定这是否是一个准确的说法,或者是否有其他原因导致我得到两个不同的答案。


请注意,即使将数据转换为浮点数,除法和加法仍然是以双精度算术进行的。这是否符合您的意图? - Patricia Shanahan
3个回答

7

1.02.0double

doublefloat 之间的算术运算将隐式地把 float 转换为 double

您需要在所有数字字面值后添加 f 后缀,强制整个表达式使用 float


我刚刚尝试了第二种情况并添加了 f 后缀。它和第一种情况一样有效。我不确定为什么会有不必要的转换为 float,如果可以使用 f 后缀代替(示例摘自维基百科)。 - But I'm Not A Wrapper Class

3

您是否正在寻找 java.lang.Math.ulp

java.lang.Math.ulp 方法返回参数值的最后一位的绝对值。对于 double 类型的参数值而言,它所表示的数与比它大的下一个浮点数之间的差值即为 ulp。


非常晚的评论,但是这个答案与机器epsilon无关 - 请参阅https://en.wikipedia.org/wiki/Machine_epsilon。 - Steve Bosman
1
当然相关。你执行 ulp(1.0)。 - jherek

1

使用Math.nextUp(1.0f)可以轻松找到严格大于1.0的最小浮点数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接