なぜX % 0
無効な式なのですか?
私はいつもX % 0
Xに等しいべきだと思っていました。ゼロで割ることはできないので、答えは当然余りX(すべてが残っている)ではないでしょうか?
なぜX % 0
無効な式なのですか?
私はいつもX % 0
Xに等しいべきだと思っていました。ゼロで割ることはできないので、答えは当然余りX(すべてが残っている)ではないでしょうか?
C ++標準(2003)は§5.6/4で次のように述べています。
[...] /または%の第2オペランドがゼロの場合、動作は未定義です。[...]
つまり、次の式はundefined-behavior(UB)を呼び出します。
X / 0; //UB
X % 0; //UB
-5 % 2
それは等しくないことにも注意してください-(5 % 2)
(ペタルは彼の答えに対する彼のコメントで示唆しているようです)。実装定義です。仕様によると(§5.6/ 4)、
[...]両方のオペランドが非負の場合、余りは非負です。そうでない場合、剰余の符号は実装定義です。
この答えは数学者向けではありません。この答えは、(数学的精度を犠牲にして)動機付けを与えようとします。
数学者: こちらをご覧ください。
プログラマー:除算0
はであることに注意してくださいundefined
。したがって、mod
除算に依存する、もundefined
です。
X
これは、正とD
;の除算を表します。積分部分と小数部分で構成されています。
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
再配置すると、次のようになります。
(X % D) = D * (X / D) - D * floor(X / D)
の代わり0
にD
:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
による除算0
はundefined
:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D
定義上、数0 <= R < D
でありQ
、
X = D*Q + R
したがって、の場合D = 0
、そのような番号は存在できません(なぜなら0 <= R < 0
)
問題を概念的に理解しやすい別の方法:
引数記号の問題を今のところ無視すると、a % b
簡単に次のように書き直すことができますa - ((a / b) * b)
。がゼロの場合、式a / b
は未定義b
であるため、その場合、式全体も定義されていない必要があります。
結局、モジュラスは事実上分割演算であるため、が定義されていない場合、同様a / b
に期待することは不合理ではありません。a % b
余りを取得するには、X % 0
最初に無限大を生成するものを計算する必要がありX / 0
、無限大の余りを計算しようとすることは実際には不可能であるためだと思います。
しかし、あなたの考えに沿った最善の解決策は、このようなことをすることです
REMAIN = Y ? X % Y : X
X % Y
整数[ 0, Y )
範囲の結果を返します。X % 0
ゼロ以上、ゼロ未満の結果を出す必要があります。
(A%B)の「divivionby 0」の場合、そのタイプはfloat(B)= b =0.0のfloatidentitymod(a、b)であり、未定義であるか、2つの実装間で異なる方法で定義されています。算術エラーを優先して、論理エラー(ハードクラッシュ)を回避します。
コンピューティング
のmod([a*b],[b])==b*(a-floor(a))
INSTREADを計算することによってmod([a],[b])
ここで、[a * b] == x軸、時間の経過[b] ==シーソー曲線の最大値(決して到達しない)==シーソー関数の一次導関数
X%0の剰余を取得するには、最初にX / 0を計算する必要があるため、無限大が生成され、無限大の剰余を計算しようとすることは実際には不可能であると思います。
しかし、あなたの考えに沿った最善の解決策は、このようなことをすることです、
ans = Y ? X % Y : X
また、C ++のドキュメントでは、X%0またはX / 0と記述されているため、値は未定義になります。
コンピューターの分割方法:
被除数から始めて、結果が除数より小さくなるまで除数を減算します。減算した回数が結果であり、残っているのは余りです。たとえば、10と3を分割するには:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
それで
10 / 3 = 3
10 % 3 = 1
1と0を分割するには:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
それで
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
停止するものがない場合、CPUは過負荷になり、完全にランダムな結果を返すまでこれを実行し続けます。NaN
したがって、除数が0の場合、またはInfinity
(プラットフォームに応じて)を返すというCPUレベルの命令があります。
これは決して終わらないので、残りは未定義です(これはNaN
コンピューター用です)。