2

ここに私の基本的な問題があります:

LOW←6     ⍝ lower bound
UPP←225   ⍝ upper bound
INC←0.01  ⍝ increment
VAL←50    ⍝ value

VAL が増分の倍数であるかどうかを判断したいと考えています。私の最初の解決策は、(VAL-LOW)÷INC が整数かどうかを確認することでした。ここで ⎕CT の問題に遭遇しました (以下は実際のコードではありませんが、私のケースを示しています)。

V←(VAL-LOW)÷INC
W←⌊0.5+|V
V
    4400
W
    4400
V=W
    0
|V-W
    1.somethingE¯13

まあ!(注: もちろん、これはコードを「素足」で実行した場合には発生しません。実際の環境でコール スタックの奥深くにある場合のみです。)

2 番目のアイデアはあまりエレガントではありませんでしたが、紙の上では適切に思えました。

V←0 12⍕(VAL-LOW)÷INC
0=⍎(1+V⍳'.')↓V

V を 12 桁に書式設定し、小数点とその左側のすべてを削除します。残りを実行し、それがゼロに等しいかどうかを確認します。それはうまくいきましたが、うまくいかず、12 ナインが残りました。

ああ!

それから、小数点以下 12 桁は必ずしも必要ではないかもしれないことに気づきました。実際、INCにあるのと同じ数だけ必要です。

DEC←(⌽⍕INC)⍳'.'
V←0 DEC⍕(VAL-LOW)÷INC
0=⍎(1+V⍳'.')↓V

わかりません... ますます乱雑になっています。UPP が巨大で INC が 1000 の場合はどうなりますか? これを行うより賢い方法はありますか?

単純な解決策は、LOW、INC、および UPP に基づいて有効な VAL のリストを生成することでしたが、このような解決策では常に作業メモリが不足する危険があります。

4

2 に答える 2

2

システムの最大値が何であれ、[]PP を 16 または 17 に設定して、見たとおりのものが得られるようにします。システムは、実際には整数値ではない場合でも、表示された値を整数値のように見せるために都合よく丸めます。これは、表示されるもの、⍕ の結果のみに影響し、計算自体には影響しないことに注意してください。精度と精度。

次に、[]CT を比較的「大きい」もの、おそらく 1e-10 または 1e-8 に設定してみてください。これにより、リレーショナル関数の動作がそれほど気難しいように見えなくなります。それが何をするか見てください。

また、比較を次のように変更してみてください。

0.000001 > | V - W

つまり、[]CT を自分で行います。[]CT を必ずゼロに設定してください。

数値が通常の整数または 64 ビット浮動小数点で表現可能な整数の範囲内 (2e50 前後) にある場合は、すべて問題ありません。

于 2014-10-14T11:23:18.577 に答える
0

これはすべてのプログラミング言語の問題であり、理解していない場合にのみ問題になります。

ほとんどの (すべて?) APL 実装の 10 進数値は、コンピューターによって 2 進浮動小数点値として格納されます。2 進数とは、整数部分と小数部分の両方が、それぞれ 2 の正と負の累乗を合計することによって作成されることを意味します。

3 = 2 + 1 = 2 1 + 2 0 = 11 バイナリで

3.5 = 2 + 1 + 1/2 = 2 1 + 2 0 + 2 -1 = 2 進数で 11.1

3.125 = 2 + 1 + 1/8 = 2 1 + 2 0 + 2 -3 = 2 進数で 11.001

0.75 = 1/2 + 1/4 = 2 -1 + 2 -2 = 2 進数で 0.11

浮動小数点とは、上位 N 個の最上位 2 進数のみが、それらを左または右に「シフト」する指数値とともに格納されることを意味します。

これは、この内部形式 (2 進浮動小数点) を使用して正確な10 進数値を格納しようとする場合にのみ問題になります。ほとんどの場合、これはできないためです。

これは、基数 10 で有限の 10 進展開を持つ多くの (有理数) 数が、基数 2 ではないためです。

0.1 = 2 -4 + 2 -5 + 2 -8 + 2 -9 + 2 -12 + 2 -13 + ... = 0.0 0011 0011 0011... (周期的)

APL 実装が「10 進」変数タイプをサポートしている場合は、それを使用できます。それ以外の場合、通常の回避策 (および「10 進」変数を提供する言語またはライブラリで通常実装される方法) は、基数 10 の整数、値、および指数を使用することです。

例: 0.00123 = 123 × 10 -5なので、整数のベクトルとして表すことができます: 123, -5

ここで楽しい部分は、そのようなベクトルに必要なすべての算術演算を APL のフレーバーで実装し、常にフードの下で整数演算のみを使用するようにします。それは読者への演習として残されています:-)

もちろん、10 進数の X 桁を超える必要がないと予想される場合は、変数がセント、1000 分の 1、100 分の 1、またはその他の分数を表すという規則に従って、通常の整数と通常の整数演算を使用できます。ところで、丸め誤差を避けるために、コンピュータ プログラムで通貨の値を処理する (する必要がある) 方法は、セントで表される整数値としてです。

于 2014-10-25T06:49:36.620 に答える