標準的な機能/アプローチの代替実装 - ページ 10

 
pavlick_:
)).これは、値の範囲を正確に知っている個人的な工芸品にのみ適するかもしれないが、標準ライブラリにはない。組み込み関数は馬鹿が書いたものではない、自分が一番賢いと思うなよ。ここで、未定義・未指定の動作も書いておいて、そのように動作しないことに驚いている友人がいますhttps://www.linux.org.ru/forum/development/14422428#comments. これらの数ナノ秒の節約は、実際のアルゴリズム(裸のループではありません)では、目に見えるものではありません。

今になってようやく、あなたの言っていたことに追いついたよ。
ループに入ってないというのは撤回します。申し訳ございませんでした。
ただし、2倍算は-9007199254740992~9007199254740992(2の53乗(仮数)のビット数)の範囲にあることが条件となります。

 
Renat Fatkhullin:
整数の範囲外で何が出るか考えてみてください。

これはどうでしょう

double Ceil (double x) { return double((x>9007199254740992 || x<-9007199254740992 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}

の結果です。

2018.08.26 10:49:23.552 TestRound (Crypto.ALT,M10)      Время цикла без округления = 1.317 наносекунд, сумма = 115583114403605978808320.00000000
2018.08.26 10:49:23.556 TestRound (Crypto.ALT,M10)      Время выполнения функции ceil =  2.129 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.557 TestRound (Crypto.ALT,M10)      Время выполнения функции Ceil =  0.100 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.560 TestRound (Crypto.ALT,M10)      Время выполнения функции floor = 1.299 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.561 TestRound (Crypto.ALT,M10)      Время выполнения функции Floor = 0.120 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.564 TestRound (Crypto.ALT,M10)      Время выполнения функции round = 1.787 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.566 TestRound (Crypto.ALT,M10)      Время выполнения функции Round = 0.106 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.566 TestRound (Crypto.ALT,M10)      Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать

このテストでは、完全に同一であることを示すようです。

ただし、この場合、範囲チェックがある別解の方が2倍程度(むしろ3~8倍)高速になりますが、これは数倍が-9007199254740992から9007199254740992までの 範囲にある場合です。しかし、この範囲を外れるともっと高くなる。

ファイル:
TestRound.mq5  9 kb
 
Nikolai Semko:


このテストでは、完全に同一であることを示すようです。

しかし、この変種はdouble 型の 入力変数が nan, snan の値を取るときのオーバーフローを考慮しません。

もしそれを考慮しなければならないなら、もうひとつチェックを加えることができますが、それでもこの変形は元の関数より速く動作するでしょう。

double Ceil (double x) { return double((!MathIsValidNumber(x) || x>9007199254740992 || x<-9007199254740992 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((!MathIsValidNumber(x) || x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((!MathIsValidNumber(x) || x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}
 
Nikolai Semko:

テスター/オプティマイザーのためにEAを書き上げる。そこで重要になるのが、実践でのスピードです。

 
fxsaber:

テスター/オプティマイザーのためにEAを書き上げる。そこで、練習ではスピードが重要です。

ご存知の方も多いと思いますが、私はスムースグラフィックスもやっています。丸め関数が活躍するのは、グラフィックの平滑化や画素単位での処理です。

以前は、丸め機能がdoubleの平方根の抽出より遅いなんて想像もつかなかった。
だからこそ、私はそのナノ秒を刻むことにしたのです。なぜなら、平滑化されたグラフ上のナノ秒は、フレームごとにミリ秒に変わり、1フレームは33ミリ秒ごとに変化する可能性があるからです。

 
Nikolai Semko:

ご存知の方も多いと思いますが、私はアンチエイリアスグラフィックスも扱っています。丸め関数が積極的に使われるのは、アンチエイリアスグラフィックスや画素単位での処理のためです。
だからこそ、そのナノ秒を滑らかにすることに取り組んできたのです。なぜなら、平滑化されたグラフィック上のナノ秒が、フレームごとにミリ秒に変わり、1フレームは33ミリ秒ごとに変化する可能性があるからです。

もちろん、これはグラフィックにとっても重要なことです。そのため、ほとんどすべての一般的なタスクに対するアルゴリズムによる最適化が、非常に長い間そこに存在していた。

 
fxsaber:

もちろん、これはグラフィックにとっても重要なことです。そのため、ほとんどすべての一般的なタスクに対するアルゴリズムの最適化が、非常に長い間そこに存在していたのです。

あなたは勘違いしています。CCanvasクラスは 最適化には程遠く、アンチエイリアシングもほとんどなく、アンチエイリアシングも満足のいくものではありません。

 

LONG_MAX/MINを 使用しないのはなぜですか?そのほうが、なんとなくまともに見えるでしょう。いい感じだと思いますよ。gccでテストしてみました(もちろん、手元にある非常に古いコンパイラ5.4.0を最小限の修正で)。

1.O3付きでコンパイルしています。

Время цикла без округления = 0.001099185 секунд, сумма = 1.15583114 e+23
Время выполнения функции ceil =  0.004310106 секунд, сумма = 1.15583114 e+23
Время выполнения функции Ceil =  0.001912712 секунд, сумма = 1.15583114 e+23
Время выполнения функции floor =  0.005283493 секунд, сумма = 1.15583114 e+23
Время выполнения функции Floor =  0.002031304 секунд, сумма = 1.15583114 e+23
Время выполнения функции round =  0.005308409 секунд, сумма = 1.15583114 e+23
Время выполнения функции Round =  0.002344382 секунд, сумма = 1.15583114 e+23

2.Ofastでコンパイルする

Время цикла без округления = 0.000552652 секунд, сумма = 1.15583114 e+23
Время выполнения функции ceil =  0.001720999 секунд, сумма = 1.15583114 e+23
Время выполнения функции Ceil =  0.00189282 секунд, сумма = 1.15583114 e+23
Время выполнения функции floor =  0.001430063 секунд, сумма = 1.15583114 e+23
Время выполнения функции Floor =  0.001979336 секунд, сумма = 1.15583114 e+23
Время выполнения функции round =  0.001698521 секунд, сумма = 1.15583114 e+23
Время выполнения функции Round =  0.001944874 секунд, сумма = 1.15583114 e+23

あなたのコードは時間計算に問題があり、出力はミリ秒単位です(ナノ秒ではありません)。

Print("Время выполнения функции ceil =  "+DoubleToString((double)(GetMicrosecondCount()-t-t0)/1000,3)+" наносекунд, Контрольная сумма = "+string(s));
 
Nikolai Semko:

間違っている。まだ耕されていない畑があり、耕されているものは閉鎖されています。

世界経験の話です。テーマ別フォーラムで、グラフのデモを作っているアルゴリズムを見てください。人々は迅速なアルゴリズムを共有しています。

 
fxsaber:

世界経験の話です。グラフのデモが作られているテーマ別フォーラムでアルゴリズムを探す。人々は高速なアルゴリズムを共有しています。

リンクを送っていただけませんか?