Java 期望n个浮点数之和为1的合适公差是多少

Java 期望n个浮点数之和为1的合适公差是多少,java,floating-point,floating-accuracy,Java,Floating Point,Floating Accuracy,我有n个浮点数,它们的和应该为1,每个浮点数可以取0到1之间的任何值。我想检查它们的总和是否为1,但如果FP数不准确,则检查总和==1是否总是有效 因此我想检查Math.abs(sum-1)更新2:浮点数乘以1,如果我在数学上考虑(例如,0.1 +…+0.1)< P>是,就可以确定使用固定精度浮点数作加法所产生的最大可能的“误差”。p> 然而,该分析的结果对于ε来说并不是一个有用的值 考虑以下示例: float a = 1.0E-37f; float b = Float.MIN_VALUE;

我有n个浮点数,它们的和应该为1,每个浮点数可以取0到1之间的任何值。我想检查它们的总和是否为1,但如果FP数不准确,则检查总和==1是否总是有效

因此我想检查Math.abs(sum-1) 更新:我理解为什么浮动是不精确的,我知道我可以用更精确的方式处理概率。我只是想了解更多关于浮动的内容


< P>更新2:浮点数乘以1,如果我在数学上考虑(例如,0.1 +…+0.1)

< P>是,就可以确定使用固定精度浮点数作加法所产生的最大可能的“误差”。p> 然而,该分析的结果对于ε来说并不是一个有用的值

考虑以下示例:

float a = 1.0E-37f;
float b = Float.MIN_VALUE;

System.out.println((a+b) == a);
System.out.println(a);
System.out.println(1.0f - a);
这张照片是:

true
1.0E-37
1.0
因此,如果对
1.0E-37f
执行任意数量的
Float.MIN_值的加法,则与
1.0f
之和的差值仍然是
1.0f

这表明,当使用无限精度时,有限精度所引入的最大误差对加起来等于
1.0
的和进行浮动,实际上是
1.0f
——显然,这对于ε是没有用处的。只有当“足够好”的要求已知时,才可能确定有用的ε-这取决于您想使用结果做什么,一般来说无法回答


当然,上面的例子有点做作,因为它突出了一个最坏的情况,在您的情况下可能不可能,这取决于
n
的实际值

正如@EricPostpischil在评论中提到的

[0,1]中任意两个数字相加的最大误差为½ULP(½),且有n个−1个加法,因此总误差最大为(n−1) •½•ULP(½)

从这个公式可以看出,需要很大的
n
值才能得出
1.0
的错误。(您可能已经注意到,在我的示例中,我选择了相对较小的值—它们加起来等于1需要很多)

输入一些数字:

int n = 33554433;
System.out.println((n-1)*0.5*Math.ulp(0.5f));
屈服

1.0
如果您的
n
要低得多,或者您知道您尚未告诉我们的输入编号的进一步限制,则可能会得到更有用的错误上限



然而,我的观点仍然站得住脚——虽然知道这个上限可能很有用,但它不能用作验证值是否“足够好”的ε。

是的,通过使用固定精度浮点数进行加法,可以确定可能出现的最大“错误”

然而,该分析的结果对于ε来说并不是一个有用的值

考虑以下示例:

float a = 1.0E-37f;
float b = Float.MIN_VALUE;

System.out.println((a+b) == a);
System.out.println(a);
System.out.println(1.0f - a);
这张照片是:

true
1.0E-37
1.0
因此,如果对
1.0E-37f
执行任意数量的
Float.MIN_值的加法,则与
1.0f
之和的差值仍然是
1.0f

这表明,当使用无限精度时,有限精度所引入的最大误差对加起来等于
1.0
的和进行浮动,实际上是
1.0f
——显然,这对于ε是没有用处的。只有当“足够好”的要求已知时,才可能确定有用的ε-这取决于您想使用结果做什么,一般来说无法回答


当然,上面的例子有点做作,因为它突出了一个最坏的情况,在您的情况下可能不可能,这取决于
n
的实际值

正如@EricPostpischil在评论中提到的

[0,1]中任意两个数字相加的最大误差为½ULP(½),且有n个−1个加法,因此总误差最大为(n−1) •½•ULP(½)

从这个公式可以看出,需要很大的
n
值才能得出
1.0
的错误。(您可能已经注意到,在我的示例中,我选择了相对较小的值—它们加起来等于1需要很多)

输入一些数字:

int n = 33554433;
System.out.println((n-1)*0.5*Math.ulp(0.5f));
屈服

1.0
如果您的
n
要低得多,或者您知道您尚未告诉我们的输入编号的进一步限制,则可能会得到更有用的错误上限



然而,我的观点仍然站得住脚——虽然知道这个上限可能有用,但它不能用作验证值是否“足够好”的ε。

这个问题提出了许多值得探讨的案例。我在下面写了一些材料,但这只是一个起点

在这个回答中,我使用以下条件:

  • 数字在中表示,算术在一些IEEE-754二进制浮点格式中执行,使用从四舍五入到最近的偶数关系
  • 我们有一个数字序列s0,s1,s2,…sn−1,其格式为(0,1),其精确数学和为1

(请注意,区间中不包括零。零的存在不会影响任何最终的和,因为加零不会改变值,因此任何包含零的序列都可以通过删除零而减少为不包含零的序列。)


定义:这个问题提出了许多值得探讨的案例。我在下面写了一些材料,但这只是一个起点

在这个回答中,我使用以下条件:

  • 数字在中表示,算术在一些IEEE-754二进制浮点格式中执行,使用从四舍五入到最近的偶数关系
  • 我们有一个数字序列s0,s1,s2,…sn−1,其格式为(0,1),其精确数学和为1

(注意,零