当前位置: 首页 > 知识库问答 >
问题:

Java:Double machine epsilon不是最小的x,因此1 x!=1.

白越
2023-03-14

我试图确定Java中的机器epsilon,使用它是最小可表示的x的定义,这样1.0 x!=1.0,就像在C/C中一样。根据维基百科,这台机器epsilon等于2^-52(52是尾数位-1的数量)。

我的实现使用Math.ulp()函数:

double eps = Math.ulp(1.0);
System.out.println("eps = " + eps);
System.out.println("eps == 2^-52? " + (eps == Math.pow(2, -52)));

结果和我预期的一样:

eps = 2.220446049250313E-16
eps == 2^-52? true

到目前为止,一切都很好。然而,如果我检查给定的ep确实是最小的x,例如1.0 x!=1.0,似乎有一个更小的,也就是根据M的前一个值ath.next在()之后:

double epsPred = Math.nextAfter(eps, Double.NEGATIVE_INFINITY);
System.out.println("epsPred = " + epsPred);
System.out.println("epsPred < eps? " + (epsPred < eps));
System.out.println("1.0 + epsPred == 1.0? " + (1.0 + epsPred == 1.0));

由此产生:

epsPred = 2.2204460492503128E-16
epsPred < eps? true
1.0 + epsPred == 1.0? false

正如我们看到的,我们有一个比机器小的ε,加上1,得到的不是1,这与定义相矛盾。

那么根据这个定义,机器ε的普遍接受值有什么问题?或者我错过了什么?我怀疑浮点数学的另一个深奥的方面,但我看不出我哪里出错了...

编辑:多亏了评论者,我终于明白了。我其实用错了定义<代码>eps=数学。ulp(1.0)计算到最小可表示双精度的距离

共有2个答案

齐英耀
2023-03-14

我不确定你的实验方法/理论是否正确。数学课程的文档说明:

对于给定的浮点格式,特定实数值的ulp是包含该数值的两个浮点值之间的距离

ulp方法的留档表示:

双倍值的ulp是这个浮点值和下一个量值更大的双倍值之间的正距离

因此,如果您想要最小的EPS值,例如1.0 EPS!=1.0,则您的EPS通常应该小于Math.ulp(1.0),因为至少对于任何大于Math.ulp(1.0)/2的值,结果将被舍入。

我认为这样的最小值将由数学给出。下一步(eps/2,1.0)

丌官炎彬
2023-03-14

将其定义为最小的可表示双值x,即1.0 x!=1.0,就像在C/C中一样

这从来都不是定义,不是在Java中,不是在C中,也不是在C中。

定义是机器ε是1和大于1的最小浮点数/双数之间的距离。

你的“定义”错了将近2倍。

此外,stritfp的缺失只允许更大的指数范围,并且不应该对epsilon的经验测量产生任何影响,因为这是从1.0及其继任者计算的,其中的每一个和其差异都可以用标准指数范围来表示。

 类似资料:
  • 几乎可以肯定,并且不仅仅是因为标准委员会要拖延C++11的期限。我听到最多的希望或计划是社区应该在C++11推出后立即开始实施。与当今科技发展水平相比,标准的发布周期太长了,所以一些人认为三年时间用来修订比较合适。而我认为5年则是更为现实的。那C++16呢? (翻译:nivo)

  • 我想要的完整标题: 错误:最小支持的Gradle版本是2.10,Gradle3.x还不支持。当前版本是2.4。如果使用gradle包装器,请尝试将...\gradle-wrapper.properties中的distributionUrl编辑为gradle-2.10-all.zip 我有一个老项目,我试图在Android Studio2.2(预览6)中打开,当我试图构建该项目时,我得到以下错误。

  • 问题内容: 我需要出于教育目的对功能进行重新编码,并且还必须命名。 当我重命名我的函数时,它可以正常工作,但是当我命名它时,该程序不知道他是否需要使用我的或系统的,即使我没有调用我的免费程序,该程序也是如此(只是另一个func 的声明似乎崩溃) 所以我怎么告诉编译器使用我的而不是系统的呢? 预先谢谢你。 编辑:Linux操作系统 问题答案: 基本上,您可以看到三个选项 在编译时重定向它,例如使用@

  • 假设n,a,b是正整数,其中n不是素数,因此n=ab和a≥b和(a)−b) 越小越好。如果给定n,找到a和b值的最佳算法是什么? 我读到了一个解决方案,他们试图通过搜索一个大于n的平方,将n表示为两个平方之间的差,这样S-n=(另一个平方)。为什么这比简单地找到n的素因子并搜索a,b是n的因子且a-b最小化的组合更好?

  • 还在纠结递归。我有一个代码,它应该让我得到最少的操作,以便从x到y。只有乘以2或加+1,例如从7到12...它的5次操作,因为你需要+1次。我的代码对我来说没有正确的工作,我无法找出我缺少了什么来保证它是正确的。

  • 生成包含位数的最低和最高整数值的最佳方法是什么? 例如: =1:Min=0,Max=9 我觉得这应该是一件非常容易完成的事情,但是我正在努力理解它背后的数学。 以下是迄今为止我得到的生成最大值的方法(基于此答案): 如果有人能帮助生成最小值,或者对上面的代码提出改进建议,我将不胜感激。 编辑 我就快到了——这似乎适用于所有情况,除非=1(最小值预期为0)