基础 · 04
计算和除法
加减乘在各语言中一样,除法却各不相同。
+ - * 在各语言中都一样,但除法和余数(%)各不相同。
下面的例子用两个数依次输出和、差、积、商、余数和小数除法的结果。
a, b = map(int, input().split())print(a + b)print(a - b)print(a * b)print(a // b)print(a % b)print(a / b)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);import { readFileSync } from "node:fs";const [a, b]: number[] = 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);import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int a = sc.nextInt(), b = sc.nextInt(); System.out.println(a + b); System.out.println(a - b); System.out.println(a * b); System.out.println(a / b); System.out.println(a % b); System.out.println((double) a / b); }}using System; class Program{ static void Main() { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int a = int.Parse(p[0]), b = int.Parse(p[1]); Console.WriteLine(a + b); Console.WriteLine(a - b); Console.WriteLine(a * b); Console.WriteLine(a / b); Console.WriteLine(a % b); Console.WriteLine((double)a / b); }}#include <iostream> int main() { int a, b; std::cin >> a >> b; std::cout << a + b << '\n'; std::cout << a - b << '\n'; std::cout << a * b << '\n'; std::cout << a / b << '\n'; std::cout << a % b << '\n'; std::cout << (double)a / b << '\n';}#include <stdio.h> int main(void) { int a, b; scanf("%d %d", &a, &b); printf("%d\n", a + b); printf("%d\n", a - b); printf("%d\n", a * b); printf("%d\n", a / b); printf("%d\n", a % b); printf("%g\n", (double)a / b); return 0;}nums = 控制台.读数字();a = nums[0];b = nums[1];控制台.输出(a + b);控制台.输出(a - b);控制台.输出(a * b);控制台.输出(数学.商(a, b));控制台.输出(a % b);控制台.输出(a / b);7 2
9 5 14 3 1 3.5
要点
- 有的语言里整数除以整数还是整数:
7 / 2→3(小数部分被舍去)。
只有一种数字类型的语言直接得到3.5。 - 需要小数结果时,要在除法之前把一边转成浮点数。
- 遇到负数,语言分成两派:向零截断(
-3.5→-3)和向下取整(-3.5→-4)。 - 整数有上限。
溢出时可能不报错,却得到错误的值。 - 除以零时,有的语言报错停止,有的语言悄悄得到
Infinity。
各语言的写法
| Python | // 求商(7 // 2 → 3),/ 总是小数(7 / 2 → 3.5,连 6 / 2 也是 3.0)。负数向下取整。 整数不会溢出。 除以零报 ZeroDivisionError |
|---|---|
| JavaScript | 只有一种数字类型,7 / 2 → 3.5。求商用 Math.trunc(a / b);Math.floor 对负数结果不同(Math.floor(-3.5) → -4)。超过 2^53 末尾几位会出错( 9007199254740993 → 9007199254740992)。除以零得到 Infinity |
| TypeScript | 和 JavaScript 一样 |
| Java | 整数 ÷ 整数是整数,要小数用 (double)a / b → 3.5。向零截断。 int 溢出时不报错,直接绕回。大数用 long。整数除以零抛出 ArithmeticException |
| C# | 和 Java 一样。 整数除以零抛出 DivideByZeroException |
| C++ | 整数 ÷ 整数是整数,要小数用 (double)a / b。向零截断。 有符号整数溢出和除以零都是未定义行为。 大数用 long long |
| C | 和 C++ 一样 |
| Craykon | 只有一种数字类型,7 / 2 → 3.5。求商用 数学.商(a, b),向下取整用 数学.向下取整。% 向零截断。超过 2^53 末尾几位会出错,除以零得到 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 是
负数除法因语言而异。
Python 是
-7 // 2 → -4、-7 % 2 → 1(向下取整);C、C++、Java、C#、JavaScript(Math.trunc)和 Craykon(数学.商)是商 -3、余数 -1(向零截断)。