3

double の精度 (桁数) を減らす関数が必要です。

画面への出力ではなく、計算に必要です。

私がこれまでに持っているものは次のとおりです。

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 は正確な double 表現を持っていません。のどこにも「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.414 を正しく取得するには、たとえば 1.873 を間違って取得するという代償を払う必要があることを忘れないでください (1.87299999999 または 1.87300000001 としてください)。 、そして計算には多かれ少なかれ同じエラーがあります。

整数演算では、最初の数値に 1,000,000 (および 1414000 を取得) または別の適切なスケールを掛けてから、最後に除算することができます。ただし、整数には上限があります。

GMP ( http://gmplib.org/ )のように、別の内部表現を使用し、必要な方法で精度を指定できる Arbitrary Precision Libraries もあります。もちろん、それで作業することは、指定するよりも困難です

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

10 番目 = 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

データを内部的に管理する中間クラスを作成できます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 に答える
-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 に答える