gpt4 book ai didi

c++ - 如何将 double 四舍五入到 n 位小数 C++

转载 作者:太空狗 更新时间:2023-10-29 23:20:52 35 4
gpt4 key购买 nike

我正在努力解决如何将 C++ 中的计算结果( double )正确舍入到小数点后 n 位。在尝试标准方法后(将数字乘以 10^n,使用“舍入”函数得到最接近的长整数,然后将该结果除以 10^n 并重铸为双倍数,如此处解释:http://en.wikipedia.org/wiki/Rounding),我发现将其应用于计算结果时会产生意想不到的结果(我想我知道答案,但显然计算机不同意)。 n=2 的示例:

#include <iostream>
#include "math.h"

int main()
{
double x 177.95d; //original number
double y yr;

y = x*(1.0d-0.3d); //perform a calculation. Should be 124.565
yr = (double) round(y/.01)*0.01; //round up y for n=2
printf("rounded value of y = %.2f\n",yr); //prints out 124.56
}

需要明确的是,我知道所涉及的所有数字都没有精确的二进制表示形式,但我不希望 double (我相信它具有大约 15 位十进制数字的精度)在近似值上有困难5 位有效(小数)数字以内的数字。由于许多程序都以这种方式对数字进行四舍五入,我认为这是可能的(对吗?)甚至电子表格也这样做......

更新:显然,我可以通过简单地提高舍入精度来实现这一点。例如:yr = (double) round(y/.0001)*0.0001;似乎对四舍五入到两位小数的数字产生了正确的结果。但是,我不太清楚小数舍入位数 (n) 与舍入函数中所需零的数量(我们称之为 m)之间的关系。

更新更新:我想我已经破解了它。首先,我注意到 double 的输出流格式化程序已经将十进制表示形式四舍五入为您请求的任何格式(例如 printf("%.2f\n",12.345) 将产生输出 12.35)。这意味着必须首先将其十进制表示形式四舍五入到第 n 个小数位的 float 或 double 转换为正确的第 (n+1) 个小数位的表示形式。现在,假设 y 的十进制表示中的累积误差 (e) << 1.0E-(n+1)(64 位 double 的机器 epsilon 大约为 2.E-16),唯一一次轮函数给出一个不好的结果是当 y 的第 (n+1) 个数字是 5,但是十进制近似给出第 (n+1) 个数字 4 并且第 (n+2) 个数字 >=5。事实上,在我给出的示例中,y 的 15 位数字的十进制近似值是 124.564999999999984——这就是一种病态情况。 round 函数必须简单地考虑这些情况。

因此,我得出结论:在四舍五入函数 (double) round(y/1.0E-m)*1.0E-m 中保证始终给出可接受结果的指数 m 的最小值是四舍五入到小数点后第 n 位的 double 等于二:m=n+2。这解释了我第一次更新的积极结果......

最佳答案

使用双舍入。第一舍入将使倒数第二个数字成为您所期望的。添加一个非常小的偏移量以抵消二进制 float 低于实际所需值的趋势,然后再次舍入。

yr = round((round(y/0.001)+0.1)/10.0)*0.01;

这不会在所有情况下都有效,但它应该比天真的方法更加一致。

关于c++ - 如何将 double 四舍五入到 n 位小数 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25610434/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com