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

计算浮点数时可能出现的最大舍入误差

湛财
2023-03-14

我正在用Java开发一个时间关键型算法,因此没有使用BigDecimal。为了处理舍入误差,我设置了一个误差上限,在这个上限之下,不同的浮点数被认为是完全相同的。现在的问题是,这个界限应该是什么?或者换句话说,当对浮点数(浮点数加、减、乘、除)执行计算操作时,可能出现的最大舍入误差是什么?

通过我做的一个实验,似乎1e-11的范围就足够了。

PS:这个问题与语言无关。

编辑:我使用的是double数据类型。这些数字是通过RandomnextDouble()方法生成的。

编辑2:似乎我需要根据我使用的浮点数的生成方式来计算错误。nextDouble()方法如下所示:

public double nextDouble() {
    return (((long)(next(26)) << 27) + next(27))
        / (double)(1L << 53); }

基于此方法中的常数,我应该能够计算出使用此方法生成的浮点数可能出现的最大错误(其机器epsilon?)。如果有人能发布计算结果,我会很高兴的。

共有2个答案

严斌
2023-03-14

这取决于:

  1. 你的算法
  2. 涉及数字的大小

例如,考虑函数<代码> f(x)=a*(b-(cd))< /代码>没有什么大不了的,不是吗?

结果是当d

让我们说:

a = 10e200
b = c = 5
d = 10e-90

这完全是编造的,但你明白了。重点是,c和d之间的量级差异意味着

c + d = c (small rounding error because d << c)
b - (c + d) = 0 (should be 10e-90)
a * (b - (c + d)) = 0 (where it really should be 10e110)

长话短说,有些运算(尤其是减法)会让你丧命。同样,你需要看的不是生成函数,而是你对数字(你的算法)所做的运算。

羊舌昆杰
2023-03-14

单次简单运算的最坏舍入误差是包含运算实数结果的两个双精度整数之间的间隙的一半。Random的nextDouble方法的结果是“从0.0d(含)到1.0d(不含)”。对于这些数字,最大的差距约为1e-16,最坏情况下的舍入误差约为5e-17。

下面是一个程序,它打印一些样本数的差距,包括Random的nextTwo的最大结果:

public class Test {
  public static void main(String[] args) {
    System.out.println("Max random result gap: "
        + Math.ulp(Math.nextAfter(1.0, Double.NEGATIVE_INFINITY)));
    System.out.println("1e6 gap: "
        + Math.ulp(1e6));
    System.out.println("1e30 gap: "
        + Math.ulp(1e30));
  }
}

输出:

Max random result gap: 1.1102230246251565E-16
1e6 gap: 1.1641532182693481E-10
1e30 gap: 1.40737488355328E14

根据您正在进行的计算,误差可能会在多个操作中累积,从而产生比您从这种简单的单操作方法中预测的更大的总舍入误差。正如马克·迪金森(Mark Dickinson)在评论中所说,“数值分析比这要复杂一些。”

 类似资料:
  • 问题内容: 我不知道这是否是一个明显的错误,但是在运行Python脚本以更改模拟参数时,我意识到缺少和的结果。在调查中,我注意到以下Python代码: 生成的相同文件的增量= 0.28和0.29,与.57和.58相同,原因是python返回float(29)/ 100为。但这不是系统错误,从某种意义上说,它并不是每个整数都发生的。因此,我创建了以下Python脚本: 而且我看不到发生这种舍入错误的

  • 我有一个关于PostgreSQL 9.2中浮点数的新手问题。 有没有直接舍入浮点数的函数,即不需要先将数字转换为数字类型? 另外,我想知道是否有一个函数可以用任意的度量单位进行取整,例如精确到0.05? 首先将数字转换为十进制形式时,以下查询工作正常: 然而,我真正想要实现的是以下几点: 这当前给了我以下错误: 谢啦

  • 我不明白为什么这是1.0。它不应该是0.999999999999吗?因此,我提出了一种解决方案,python对其答案进行了自动舍入,但如果大于,则无法解释以下结果。。。 我以为四舍五入错误是因为尾数中使用的位数有限,指数(浮点数),但0.9999~~9也没有超出位数的限制...有人能解释一下为什么这些结果会这样吗?

  • 我试图编写一个round_up函数,将浮点数转换为整数,但是我获取小数位数的方法似乎有错误(浮点数%1的剩余部分)。如果浮点数是4.4,我希望将其转换为4;如果是4.5,我希望将其转换为5。错误消息:错误:无效的操作数到二进制%(有'浮动'和'int')

  • 我写了这段代码,它只是对n个数字的列表进行求和,以练习浮点运算,但我不明白这一点: 我正在使用float,这意味着我有7位精度,因此,如果我执行10002*10002=100040004的操作,数据类型float的结果将是100040000.000000,因为我丢失了第7位以外的任何数字(程序仍然知道指数,如图所示)。 如果此程序中的输入是 然而,您将看到,当这个程序计算30003*30003=9

  • 这是我的作业: 编写一个程序来读取非负整数列表,并显示最大整数、最小整数和所有整数的平均值。用户通过输入不用于查找最大值、最小值和平均值的负前哨值来指示输入结束。平均值应为类型的值,因此将使用分数部分进行计算。 我得到了不同的部分来使用不同的方法:方法A使最大值和最小值正确,求和错误,方法B使求和和最大值正确,最小值错误。以下代码演示了方法B。一些变量被注释掉: 当我运行这个测试时,最大值、总和、