我需要一个降低双打精度(位数)的函数。
我需要它进行计算,而不是屏幕上的输出。
到目前为止,我的目标是:
double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
_number *= tenth;
_number = floor(_number);
_number /= tenth;
return _number;
}
调用setDigits(sqrt(2),3)
给出1.4139999999999999,而不是我想要的1.414。
我该怎么办?
答案 0 :(得分:4)
我该怎么办?
不幸的是,根本问题没有:在你的平台上,1.414没有精确的双重表示。您无法使用“1.414”运行计算,因为您无法在 double
中的任何位置放置“1.414”。
请参阅示例http://www3.ntu.edu.sg/home/ehchua/programming/java/DataRepresentation.html。
您需要计算机器精度并在计算过程中跟踪误差。
所以你将使用1.413999999999997,最后得到答案,比如41.99999137;你将用
显示printf("The answer is %.3f\n", theAnswer);
或者您可以更改平台(编译器,数学库或浮点表示,例如在支持的位置使用long double
),但请记住,您可以以获得的价格获得1.414,比如1.873错误(将其设为1.87299999999或1.87300000001),计算会有或多或少相同的错误。
您可以使用整数运算,将初始数乘以1,000,000(并获得1414000)或其他合适的比例,然后在结尾处进行除法。但是,整数具有最大限度。
还有使用不同内部表示的任意精度库,您可以按照自己的方式指定精度,例如GMP(http://gmplib.org/)。当然,使用它比指定
更困难op1 = 6.0;
op2 = 7.0;
theAnswer = op1 * op2;
并且处理速度也较慢,但结果很好 - 或者说你说的好。
答案 1 :(得分:3)
以下行无效。
double tenth = pow((double)10,_decimals); //_decimals is not declared
_number = floor(_digits); //should be floor(_number)
更正的功能是
double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
_number *= tenth;
_number = floor(_number);
_number /= tenth;
return _number;
}
答案 2 :(得分:0)
double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
int result = (_number * tenth) + 0.5;
double aux = result / tenth;
return aux;
}
试试这个。对于你的第十个= 1000的例子;
result = 1413,9999999999999 * 1000 +0,5
result = 1414,4......
result = 1414
答案 3 :(得分:0)
我不知道你可能不会检查这个答案,但其他人会这样做 我是c ++的新手,但我找到了一种方法来做到这一点
double Point::norm()
{
return (double)floor((sqrt(pow(px,2)+pow(py,2)+pow(pz,2))*1000))*0.001;
}
我使用这个,但你可以编写自己的数学课来为你做这个
答案 4 :(得分:-1)
试试这个:
double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
return floor(_number * tenth + 0.5)/tenth;
}
std::cout<<setDigits(sqrt(2),3);
Output: 1.414
答案 5 :(得分:-1)
您可以创建一个中间类,在内部管理数据为int
,但输入和输出为double
:
class TruncatedDouble
{
private:
int value_;
public:
TruncatedDouble(double d) : value_((int)(double * 1000)) {}
void SetValue(double d) {value_ = (int)(double * 1000);}
double GetValue() {return (double)value_ / 1000;}
};
你必须超载所有常用的操作员,但这很容易。例如:
TruncatedDouble& operator+=(const TruncatedDouble& rh) {value_ += rh.value_;}
等等。这个类实际上会非常快,因为您使用的是int
而不是double
,并且您永远不会失去精确度。