{ }codelper

学ぶ › JavaScript

基礎 · 04

計算と割り算

足し算・引き算・掛け算は同じですが、割り算は言語ごとに違います。

+ - * はどの言語でも同じですが、割り算と余り(%)は言語ごとに違います。
下の例は2つの数で、足し算・引き算・掛け算・商・余り・小数の割り算を順に表示します。

const [a, b] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);console.log(a + b);console.log(a - b);console.log(a * b);console.log(Math.trunc(a / b));console.log(a % b);console.log(a / b);
stdin
7 2
stdout
9
5
14
3
1
3.5

ポイント

  • 整数どうしで割ると整数になる言語があります:7 / 2 → 3(小数部分は捨てます)。
    数の型が一つの言語は、そのまま 3.5 です。
  • 小数の結果が必要なら、割る前に片方を小数の型に変えます。
  • 負の数を割ると、言語は二手に分かれます。
    0 の方向へ切り捨てる側(-3.5 → -3)と、小さい方へ切り下げる側(-3.5 → -4)です。
  • 整数には限界があります。
    あふれる(オーバーフロー)と、エラーなしでおかしな値になることもあります。
  • 0 で割るとエラーで止まる言語もあれば、黙って Infinity を返す言語もあります。

言語ごとの書き方

Python// は商(7 // 2 → 3)、/ は常に小数(7 / 2 → 3.5、6 / 2 も 3.0)。
負の数は切り下げ。
整数はあふれません。
0 で割ると ZeroDivisionError
JavaScript数の型が一つなので 7 / 2 → 3.5。
商は Math.trunc(a / b)。
Math.floor は負の数で違います(Math.floor(-3.5) → -4)。
2^53 を超えると下の桁が狂います(9007199254740993 → 9007199254740992)。
0 で割ると Infinity
TypeScriptJavaScript と同じです
Java整数 ÷ 整数は整数、小数は (double)a / b → 3.5。
0 の方向へ切り捨て。
int があふれるとエラーなしで一周します。
大きな数は long。
整数を 0 で割ると ArithmeticException
C#Java と同じです。
整数を 0 で割ると DivideByZeroException
C++整数 ÷ 整数は整数、小数は (double)a / b。
0 の方向へ切り捨て。
符号付き整数のオーバーフローと 0 での割り算は未定義動作です。
大きな数は long long
CC++ と同じです
Craykon数の型が一つなので 7 / 2 → 3.5。
商は 数学.商(a, b)、切り下げは 数学.切り下げ。
% は 0 の方向へ切り捨て。
2^53 を超えると下の桁が狂い、0 で割ると Infinity

よくある間違い

x % 2 == 1 で奇数を探したJava · C# · C · C++ · JavaScript · TypeScript · Craykon

int x = -3;
printf("%d\n", x % 2);

→ -1 — だから x % 2 == 1 は偽になり、負の奇数を見逃します

x % 2 != 0 と書きます。
どの言語でも安全です。

割ったあとで小数に変えたJava · C# · C · C++

int a = 7, b = 2;
double d = (double)(a / b);

→ 3.0 — 括弧の中の整数の割り算が先に終わります

割る前に変えます:(double)a / b → 3.5。

int があふれたJava · C# · C · C++

int x = 2147483647;
x = x + 1;

→ Java・C# はエラーなしで -2147483648。C・C++ は未定義動作です

大きな数は long(C・C++ は long long)を使います。

言語ごとの違い
負の数の割り算は言語によって違います。
Python は -7 // 2 → -4、-7 % 2 → 1(小さい方へ切り下げ)、C・C++・Java・C#・JavaScript(Math.trunc)・Craykon(数学.商)は商 -3、余り -1(0 方向へ切り捨て)です。

練習問題