3

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

我需要它来计算,而不是在屏幕上输出。

到目前为止,我所拥有的是:

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。

我能做些什么?

4

6 回答 6

5

我能做些什么?

不幸的是,根本问题没有:在您的平台中,1.414 没有精确的双重表示。您无法使用“1.414”运行计算,因为您无法将“1.414”放置 double.

参见例如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.873 为代价获得 1.414(将其设为 1.87299999999 或 1.87300000001) , 计算会有或多或少相同的误差。

您可以使用整数算术,将初始数字乘以 1,000,000(得到 1414000)或其他合适的比例,然后在最后除。不过,整数有一个最大界限。

还有一些任意精度库使用不同的内部表示,并允许您以您想要的方式指定精度,例如 GMP ( http://gmplib.org/ )。当然,使用它比指定更困难

op1 = 6.0;
op2 = 7.0;
theAnswer = op1 * op2;

并且处理速度也较慢,但结果很好 - 或者与您告诉他们的一样好。

于 2012-10-26T10:42:21.843 回答
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;
}

这是一个演示。

于 2012-10-26T10:54:27.970 回答
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
于 2012-10-26T13:37:30.187 回答
0

我不知道你可能不会检查这个答案,但其他人我是 C++ 新手,但我找到了一种方法来做到这一点

double Point::norm()

{

return (double)floor((sqrt(pow(px,2)+pow(py,2)+pow(pz,2))*1000))*0.001;

}

我用这个,但你可以编写自己的数学课来为你做这个

于 2013-05-19T08:36:11.583 回答
-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

于 2012-10-26T10:32:17.193 回答
-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,并且您永远不会失去精度。

于 2012-10-26T10:56:20.987 回答