【问题标题】:How to handle precision in Floating point arithmetic in C如何在 C 中处理浮点运算的精度
【发布时间】:2009-09-16 12:20:24
【问题描述】:

在编程竞赛中,与浮点运算相关的问题说“错误是答案必须小于 1e-6”或“答案必须正确到小数点后 6 位”。这是否意味着我可以对 FP 变量执行计算而不用担心精度,并且只有在打印时我应该像这样写

printf("%.6lf",a);

我理解正确吗?以上2个引号是不是同一个意思? 在其中一个问题中,当我使用双精度数组并执行一些计算并打印其中一个数组元素时。它打印了“-0.000000”。这是什么意思? 但是当我在 C++ 中使用向量时,比如

vector<double> arr(10,0.0);

同样的计算打印出“0.000000”。为什么会有这样的区别?

【问题讨论】:

  • 为了尽可能地保持精度,你必须优化你的计算(例如,不要将具有非常不同的指数值的数字相加,不要将太小或太大的数字相乘。而是将小数字与大数字相乘如果可能,对细分进行排序,使 sub 结果的 abs 大约为 1.0 .. 等等)

标签: c floating-point


【解决方案1】:

如果您需要 6 个小数位的精度,请至少使用双精度数。根据您正在执行的浮点计算次数,蝴蝶效应很容易影响您的答案。

浮点数的 IEEE 标准有带符号的零。 see here

【讨论】:

    【解决方案2】:

    准确性不仅取决于所使用的类型,还取决于您如何计算事物。

    例如你想计算这个:

    1e9 + 1e-9 - 1e9

    正确的答案应该是 1e-9,但是按照这个顺序执行,1e-9 在添加到 1e9 时会丢失并给出 0。

    使用 float 或 double 不足以确保获得正确的 6 位数字。您必须估计每一步可能出现的错误。

    你应该阅读Numerical analysis

    【讨论】:

      【解决方案3】:

      1e-06 的错误是 0.000001,影响小数点后 6 位,但我认为只有书呆子才会坚持这两个引号之间存在差异。 (我是一个,需要一个人才能知道一个)

      将精度保留到小数点后 6 位的要求可能是为了提醒您,计算的精度仅与计算中使用的最不准确的数字一样多。

      因此,如果您使用 3.1416 作为 PI,则无法将圆的周长计算到小数点后 6 位,无论您测量半径的精度如何

      【讨论】:

        【解决方案4】:

        在浮点数中,算术符号不是数字的一部分,所以既有 -0 又有 0。

        【讨论】:

        • 但是为什么只有一个简单的数组和向量就显示出差异
        • 应该没有任何差异。
        • 我们需要多看一点你的代码,还要知道你的编译器是用来检查 printf 在显示 6 位小数时到底做了什么
        【解决方案5】:

        没有办法知道 float 是否足够,或者您是否必须使用 bool 甚至更好的精度;一些算法会迅速破坏精度。例如,通过对渐近序列求和来计算值,您可能会达到任何太低精度(无论是 5 位还是 15 位)都会爆炸的程度。您可以阅读此类内容,例如 in this blog post

        在那篇博文中,为什么他的“浮点”(Python 浮点 = 双精度)失败了,但他自己的例程却成功了?他的例程不仅可以使用任意精度,还可以监控计算以在误差上升时增加精度。只有这样你才能确定。

        【讨论】:

          【解决方案6】:

          Blockquote 上面两个引号是不是同一个意思?

          显然不是。 1-e6 表示您的答案必须在正确的 0.000001 以内。 6 位精度意味着 12345678 是正确的,即使答案是 12345689。差异远大于 0.0000001。现在,如果您的答案是 0.100001(正确答案是 0.100000),那么它们是相同的。

          【讨论】:

          • 所以我只是以双精度数据类型进行计算,并以 6 位小数精度报告答案,我使用 %.6lf。这是正确的还是有任何舍入函数可以将其舍入到小数点后 6 位
          • 措辞是小数点后6位,通常表示正确到小数点后6位
          • stonemetal 描述的精度是6位有效数字
          • @aditya 这真的取决于您使用的数字。如果您的答案是数千个,那么不使用双精度数不会让您精确到小数点后六位。只会让您获得小数点后三位的精度,并且您将需要使用任意精度数学库。如果您的答案少于一个,请使用双打。
          猜你喜欢
          • 2018-08-27
          • 2022-01-20
          相关资源
          最近更新 更多