ceil(),round(),floor()関数の実行速度 - ページ 3

 
Nikolai Semko:

はい、でも、もし。

であれば、問題ないでしょう。

どんな数字xでもOKなのかは、まだわからない。
 

A100:

void OnStart()
{
        Print( (int)(3.0001 + 0.999999999999999)); //все равно 4
        Print( floor(3.00001));                    //3
}




理解できない。何が問題なのか?

 
A100:
どんな数字xでもOKになるかは、まだわからない。

もちろん、そんなことはないのですが...。

やはり、こうなってしまうと

double x=3;
x=x+0.1;
x=x+0.1;
x=x+0.1;
x=x+0.1;
if (x!=3.4) Print("oppps..."); // oppps...

となると、質問は私にもこの考えにも関係ない。

 
Nikolai Semko:
何が問題なのか?
void OnStart()
{
        double d =  16 + 0.999999999999999;
        Print( (int)(d + 0.999999999999999)); //18
        Print( (int)ceil( d ));               //17
}
 
A100:

前号を 見る

 
Nikolai Semko:
となると、質問は私にも、このアイデアにもないのです。
floor()、ceil()、round()は質問を避けるためにあります。
 

16桁レベルの精度を必要とする人は少ないので、正の整数の丸めを高速化する本ソリューションは、上記のような欠点もすべて実用範囲内だと思います。そして、これらのバグは、コンパイラ自体のドットレベルでのあらゆる種類のオーバーフローから発生する。

 
A100:
Floor()、ceil()、round()はそのために存在する - だから質問はない

使うことを禁止しているわけではありません。ぜひ使ってみてください。自分でも使ってみようと思います。しかし、もし私が速度を重視するアルゴリズムを作るなら、この丸め方のニュアンスをすべて考慮して、この丸め方を使うでしょう。この代替手段の存在を知ることは、他のプログラマーにとっても有益なことだと思います。この丸め方のニュアンスを知るために、まさにディスカッションが必要なのです。ありがとうございました。私は間違っているだろうか?

 
Nikolai Semko:

DBL_MINDBL_EPSILON は動作しません - 小さ すぎます。おそらく、0.999999999999(16ナイン - doubleの小数点以下の最大桁数)のままにするのが理にかなっています。

つまり、DBL_EPSILONは、小数点以下16桁:2.2204460492503131e-016と なります。

あなたの場合、差が1e-16とεの2倍しかないので、実際に1個得していることになります。

 
Alexey Navoykov:

つまり、DBL_EPSILONは小数点以下16桁:2.2204460492503131e-016と なります。

そして、あなたの場合は、その差が1e-16と、εの2倍しかないので、実際に得をしているのです。


ああ、それはわかるが、うまくいかないんだ。16ナインでも動作しないことが判明(不思議、以前は動作していたような気がする)。15ナインでしか使えない。

double x=3;
int Y=(int)ceil(x);
Print(Y);                         // 3
Y=(int)(x+0.999999999999999); 
Print(Y);                         // 3  (15 9-ток)
Y=(int)(x+0.9999999999999999);
Print(Y);                         // 4  (16 9-ток)
Y=(int)(x+1-DBL_EPSILON);
Print(Y);                         // 4