减少C ++中Double的数字

时间:2012-10-26 10:31:04

标签: c++ function double precision digit

我需要一个降低双打精度(位数)的函数。

我需要它进行计算,而不是屏幕上的输出。

到目前为止,我的目标是:

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。

我该怎么办?

6 个答案:

答案 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;
}

Here is a demo.

答案 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,并且您永远不会失去精确度。