整数

整数

スケールがゼロ以外の場合、3%2 や 46%4 などの % を使用した計算では 0 が出力される傾向があります。スケールが 0 以外の場合、アルゴリズムはどのように設計されていますか?

bc
scale=10
print 4%3   // output 0

答え1

コマンドマニュアルBC がモジュロを計算する方法については、次のように述べられています。

式の結果は「剰余」であり、次のように計算されます。a%bを計算するには、まず1/2 ...は桁数に応じて計算されます。その結果は計算に使用されますa - (a/b) * b (ア)scale+scale(b)とscale(a)の最大値のスケールに。スケールがゼロに設定され、両方の式が整数の場合、この式は整数剰余関数になります。


編集: GNU BC のソース コードを確認したところ、mod 演算子が除算演算子を拡張していることがわかりました。つまり、剰余は除算の副産物として計算されます。剰余を計算するには整数除算を使用します。scaleただし、 が設定されている場合は、整数除算は行われません。

BC でこれを試してください:

bc
scale = 0
print 5/2

scale = 5
print 5/2

次のような結果になるはずです:

2        << Integer Division
2.50000  << NOT integer division!

さて、これらの数字をBCと同じように入力してみましょう。マニュアルには次のように書かれています。a-(a/b)*b計算します。整数除算の結果とscale0 以外の値の 2 つの結果を代入してみましょう。

a - ( a/b ) * b
5 - ( 2   ) * 2  = 1  << CORRECT!
5 - ( 2.5 ) * 2  = 0  << VERY WRONG!

整数除算なし:

a - ( a/b ) * b == a - (  a  ) == 0

このため、モジュロが正しく機能するにはスケールを0に設定する必要があります。
この問題は、BCの設計と、それが「スケール」を持つ数値をどのように処理するかから生じているようです。モジュロが正しく機能するためには整数除算が必要です

がある他の多くのより高度なツールこれらはこの目的のために無料でオープンソースで提供されていますので、使用することをお勧めします。

答え2

user272970 さんの回答は素晴らしいです。ここに少し手を加えます:

define int(x) { auto oldscale; oldscale=scale; scale=0; x=x/1; scale=oldscale; return( x ); }
define fmod(x,y) { auto oldscale; oldscale=scale; scale=1000; x = x - y * int(x/y); scale=oldscale; return( x ); }

これにより ( を使用auto oldscale)、 はoldscale関数に対してローカルになります。これがないと、fmod() から を設定すると、 に保存しようとしている が上書きされoldscale、を呼び出す前の値ではなく 1000 に設定されます。int()oldscalefmod()scalefmod()

これらの関数を に追加し~/.bcrcBC_ENV_ARGS環境変数を に設定しました。これにより、bc を実行するたびにこれらの関数がロードされます。そのため、毎回これらの関数を手動で定義しなくても、bc にいるときはいつでも~/.bcrc実行できるようになりました。fmod(x,y)

1000psscaleはほとんどの場合やりすぎかもしれない

答え3

私は次のように解決しました:

整数

int(x) を定義します { oldscale=scale; scale=0; x=x/1; scale=oldscale; return( x ); }

モジュロ

mod(x,y) を定義します { oldscale=scale; scale=1000; x = x - y * int(x/y); scale=oldscale; return( x ); }

HTH

答え4

a%b他の回答者が述べているように、これはを として定義し(a-(a/b)*b)、現在の で評価した結果ですscale。つまり、これを整数係数として機能させたい場合は、 で使用する必要がありますscale=0

しかし、私はそれが「間違っている」という意見には同意しません。これは、特にエラーを評価する場合に潜在的に有用なツールです。

scale=5
1/3
> .33333
1%3
> .00001

7/134桁の小数で表すと何が失われるのでしょうか.5384?

scale=4
7/13
> .5384
7%13
> .0008

どうやら0.0008/13

そして最後に、整数の使用を要求しないため、小数の一部を抽出するのに使用できます。

scale=1
123.456/1
> 123.4
123.456%1
> .056

関連情報