如何将双精度四舍五入到小数点后n位c++
how to round up doubles to n decimal places c++
我很难正确地将c++中的计算结果(双精度)四舍五入到小数点后n位。在尝试标准方法(将数字乘以10^n,使用"round"函数获得最接近的长整数,然后将结果除以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 = %.2fn",yr); //prints out 124.56
}
需要明确的是,我知道所有涉及的数字都没有精确的二进制表示,但我不希望双精度(我相信它的精度约为15位小数)在将数字近似到5位有效(小数)以内时出现问题。由于许多程序都以这种方式对数字进行舍入,我认为这是可能的(对吧?)即使是电子表格也会这样做。。。
更新:显然,我可以通过简单地提高舍入精度来实现这一点。例如:yr=(双)圆(y/.0001)*0.0001;对于四舍五入到小数点后两位的数字,似乎产生了正确的结果。然而,我无法完全弄清楚小数点舍入位数(n)和舍入函数中所需零的数量之间的关系(我们称之为m)。
更新更新:我想我已经破解了。首先,我注意到,doubles的输出流格式化程序已经将十进制表示四舍五入到您请求的任何格式(例如printf("%.2f\n",12.345)将产生输出12.35)。这意味着,其十进制表示四入到小数点后第n位的浮点或doubles必须首先转换为其小数点后(n+1)位正确的表示。现在,假设y的十进制表示中的累积误差(e)是<lt;1.0E-(n+1)(64位双精度的机器ε约为2.E-16),舍入函数唯一一次给出坏结果是当y的第(n+1)位为5时,但十进制近似值给出第(n+1)位为4,第(n+2)位>=5。事实上,在我给出的例子中,y到15位的十进制近似值是124.56499999984——这就是一个病态的例子。round函数必须简单地说明这些情况。
因此,我得出结论:四舍五入函数(双精度)舍入(y/1.0E-m)*1.0E-m中所需的指数m的最小值,保证始终为舍入到小数点后第n位的双精度提供可接受的结果,比这多等于2:m=n+2。这解释了我第一次更新的积极结果。。。
使用双舍入。第一个四舍五入将使倒数第二个数字符合您的期望。添加一个非常小的偏移量,以抵消二进制浮点数低于实际期望值的趋势,然后再次四舍五入。
yr = round((round(y/0.001)+0.1)/10.0)*0.01;
这不会在所有情况下都有效,但它应该比天真的方法更加一致。
- 用c++把小数点转换成八进制
- 如何在 c++ 中将小数点后两位数的浮点数分配给另一个浮点数
- 使用 cin 时接受小数点后的 2 位数字
- 使用 stod() 转换小数点后字母的字符串时没有例外
- 如何在C++中只打印小数点而不设置限制,但动态设置精度
- 为什么在C++算术函数中加".0"会给出小数点的答案?
- C++ cout 列表,其中小数点使用 setw(x) 对齐,而不是put_money
- C++小数点后有 200 位数字的类型?
- 如何输出计算到小数点后两位的中间器?
- 如何在C或C 的小数点后两个位置后四舍五入
- 在C 中显示小数点,计算问题
- 所有测试用例都将小数点转换为二进制数
- 在函数定义中使用特征库时,小数点不会按预期存储
- 如何在C ++中打印特定位数的位数?例如,总共打印8位数字(小数点之前+之后的组合)
- 有人可以解释为什么这个程序可以计算小数点后的位数
- 小数点后提取值
- 如何在 C++ 中编写带有小数点的浮点值
- C++ 在数字开头添加小数点的任意方法
- 在 c++ 中显示小数点后五位数字,但如果小数点后有 0,请不要打印它们
- 将数字设置在小数点后的浮子中