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

 
Nikolai Semko:

すでにここに 書きました。

このターミナルの中で、与えられた精度の中で書いているということは、他のデバイスやプラットフォームへの移植や実行には興味がないのでしょう。

よろしくお願いします。

追伸:優れたプログラマーは、ハードウェアやプログラムが変わる可能性があることを理解し、将来的にバグを回避する必要があるはずです。
 
Andrey Kisselyov:
与えられた端末の範囲内で、その精度の範囲内で書くのであれば、他の端末やプラットフォームへの移植や動作は全く興味がない。

敬具

その通りです。MQL5(おそらくMQL4も)の話です(確認してません)。また、クラスやアルゴリズム内のコードは、MQL内で完全に引き継ぐことができます。しかし、C++でも動作します。すでにいくつかの事例があります。

 
Andrey Kisselyov:

追伸:優れたプログラマーは、ハードウェアやプログラムが変化する可能性を理解し、将来的にエラーを回避する必要があります。 あなたのようなタスクでは、その時点では無謬と考えている関数のエラーを将来的に見つけるのは簡単ではないかもしれません。
このような状況では、あなたの言うような変化を想像することさえ不可能です。(int)(x+0.5)を計算する数学で何が変わる可能性があるのか?端数部分を 捨てなくなるとか、どうなんでしょう?
 
Nikolai Semko:
このような状況では、あなたの言うような変化を想像することすら不可能です。(int)(x+0.5)を計算する数学で何が変わるのでしょうか?端数 部分を落とさなくなるのでしょうか?

例えば、新しいデータ型が 導入されるとか・・・。

 
STARIJ:

例えば、新しいデータ型が 導入される・・・。

)))はい、でも、古いデータ 型をキャンセルすると、コードが動かなくなります...。
 
この騒動のことだ。
y=(int)(x+0.9999999999999997);

例として挙げてみましょう。
のビット数まで変更すると、64ビットに変更して機械の精度が上がった場合、誤差で設定しているよりもはるかに高い精度になるため、計算式が機能しなくなります。

敬意を込めて。

P.S. 数値の範囲であなたの式が失敗する他のオプションがあるかもしれません。別のマシンに切り替えたり、コンパイラの変更、あなたが知らされていない、またはマシンの数字の表現を変更したとき、または端末の新しいバージョンをコンパイルするときに数の小数部分を カットすることから、常にエラーを調整する......何が変わるかわからないし、何度もエラーを書いて推測してIFをしたり苦しむのは良くないと思うのですが...。

それは考えるべきことだと思います。

 
Andrey Kisselyov:

...

追伸:doubleは定義上、整数にはなり得ないので、マシンメモリ上の数値の表現は変わりません。

もしかして、doubleは整数データ型ではないと言っているのであって、double型の 変数に整数値を持つ数値を格納できないと言っているのではないのでしょうか?integer doubleは整数になります。

 

コンピュータに実装されている丸め処理と単純な積み上げ後の切り捨ての違いについて、わかりやすい解説を発見。14歳、http://delphimaster.net/view/14-10885/all。

Tolik(2003-08-13 11:04)[11]です。

このような四捨五入は、会計上認められています。つまり、税務署もこの四捨五入を適用しているので、少なくとも書類上ではすべて足し算になるはずです :))



ダイヤモンドシャーク(2003-08-13 11:20) [12]

オホホホ...もう一度。
一様乱数に近い数の分布があるとする。そして、"算術 "丸めによって、次のようになります。

数字 不確実性
0 0
1 -1
2 -2
3 -3
4 -4
5 +5
6 +4
7 +3
8 +2
9 +1

このように、数字の羅列が多い場合(書類項目の合計、口座残高など)、「算術」丸めでは系統的な誤差が蓄積され、次のようなことが予想されます。
0.5*10^n * 0.1*N
のところです。
n -- 丸め処理を行う桁の十進数重み(2桁にn=-2,整数にn=0,など)
0.1が各桁の確率
Nは配列の整数の個数

誤差の確率を等しくするために、唯一補償されない(上の表を参照)誤差+5を補償する必要があります。これは、前の桁のパリティに応じて、同じ確率で+5 -5の2つに人為的に分割することで実現されています。

ちなみに、FPUのステータスワードには、丸めモード(算術/会計)を制御するチェックボックスがある。


引用終わり。

もうひとつ、http://delphimaster.net/view/15-1340952214/all。"平均的なユーザー(マネージャーや会計士)は、なぜ12.5と13.5を丸めると違う結果になるのか説明できないため "です。


丸め関数の「高速化」バージョンをユーザーに提供する場合、加算時の誤差が大きくなることを強く警告する必要があります。この誤差は、非常に異なる状況で慎重に評価する必要があるでしょう。危険だし、ミスの蓄積もある。四捨五入が重要で、それが積み重なった誤差を忘れるような例は、なかなか思いつきません。

Округление чисел. Неужели ТАК правильно???
  • delphimaster.net
3-10545           Kati                  2003-08-12 10:13  2003.09.04   обновление SQL запроса 14-10898          kalishenko            2003-08-14 20:09  2003.09.04   Win2000 Server и доступ в Интернет 1-10692           lww                   2003-08-20 10:30  2003.09.04   Как написать dll для 1С? 1-10813           koks                  2003-08-20...
 

Andrey Kisselyov:
я говорю про вот это безобразие

y=(int)(x+0.9999999999999997);

さて、皆さん、言いたいことはわかりました。ceil関数を変更してあげる。

y=ceil(x);  ->  y=(x-(int)x>0)?(int)x+1:(int)x;
или через дефайн:
#define _ceil(x) (x-(int)x>0)?(int)x+1:(int)x

この variant は variant:y=(int)(x+0.9999999997); より 25-50%遅いですが、最大限正しく、負の整数に対しても動作し、 ceil(x) より 3 倍速く なります。

というのも、あなたがたの主張はつまらないし、長い間アセンブラでプログラミングをしてきて、コンパイル後にコードがどうなるかを知っている私にとっては、チェックしなくても済むところにチェックを入れるのはやりすぎだからです。

 

正負の数値に対応したバリアント。

#define _ceil(x) (x-(int)x>0)?(int)x+1:(int)x
#define _round(x) (x>0)?(int)(x+0.5):(int)(x-0.5)
#define _floor(x) (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x
これは、ceil(),round(),floor()の本格的な置き換えと思われ、3〜4倍のスピードアドバンテージを得ることができる。