Go 允许算术运算溢出而不是抛出异常是预期的行为吗?
Is it expected behavior that Go allows overflow for arithmetic operations instead of throwing an exception?
我正在将一些 Go 代码移植到 Rust,我意识到当乘法期间发生溢出时 Rust 会崩溃,而 Go 允许发生溢出。
下面的测试代码,不会导致溢出但会打印减少的值。
(测试通过:https://play.golang.org/)
func main() {
fmt.Println("test\n")
var key uint64 = 15000;
key = key*2862933555777941757 + 1
fmt.Println(key)
}
For unsigned integer values, the operations +, -, *, and << are computed modulo 2n, where n is the bit width of the unsigned integer's type. Loosely speaking, these unsigned integer operations discard high bits upon overflow, and programs may rely on "wrap around".
For signed integers, the operations +, -, *, /, and << may legally overflow and the resulting value exists and is deterministically defined by the signed integer representation, the operation, and its operands. Overflow does not cause a run-time panic. A compiler may not optimize code under the assumption that overflow does not occur. For instance, it may not assume that x < x + 1
is always true.
如上所述,溢出存在并且不会导致 run-time 恐慌。
但必须小心,就好像你有一个 constant expressions,因为它们具有任意精度,如果结果要转换为不适合目标类型有效范围的固定精度, 它会导致编译 time-error.
例如:
const maxuint64 = 0xffffffffffffffff
var key uint64 = maxuint64 * maxuint64
fmt.Println(key)
以上结果:
constant 340282366920938463426481119284349108225 overflows uint64
maxuint64 * maxuint64
是一个常量表达式,计算得当(它的值为340282366920938463426481119284349108225
),但是当这个值要赋给key
类型的[=16]变量时=],它会导致 compile-time 错误,因为此值不能由 uint64
类型的值表示。但这不是 run-time 恐慌。
查看相关问题:
How to store a big float64 in a string without overflow?
我正在将一些 Go 代码移植到 Rust,我意识到当乘法期间发生溢出时 Rust 会崩溃,而 Go 允许发生溢出。
下面的测试代码,不会导致溢出但会打印减少的值。 (测试通过:https://play.golang.org/)
func main() {
fmt.Println("test\n")
var key uint64 = 15000;
key = key*2862933555777941757 + 1
fmt.Println(key)
}
For unsigned integer values, the operations +, -, *, and << are computed modulo 2n, where n is the bit width of the unsigned integer's type. Loosely speaking, these unsigned integer operations discard high bits upon overflow, and programs may rely on "wrap around".
For signed integers, the operations +, -, *, /, and << may legally overflow and the resulting value exists and is deterministically defined by the signed integer representation, the operation, and its operands. Overflow does not cause a run-time panic. A compiler may not optimize code under the assumption that overflow does not occur. For instance, it may not assume that
x < x + 1
is always true.
如上所述,溢出存在并且不会导致 run-time 恐慌。
但必须小心,就好像你有一个 constant expressions,因为它们具有任意精度,如果结果要转换为不适合目标类型有效范围的固定精度, 它会导致编译 time-error.
例如:
const maxuint64 = 0xffffffffffffffff
var key uint64 = maxuint64 * maxuint64
fmt.Println(key)
以上结果:
constant 340282366920938463426481119284349108225 overflows uint64
maxuint64 * maxuint64
是一个常量表达式,计算得当(它的值为340282366920938463426481119284349108225
),但是当这个值要赋给key
类型的[=16]变量时=],它会导致 compile-time 错误,因为此值不能由 uint64
类型的值表示。但这不是 run-time 恐慌。
查看相关问题:
How to store a big float64 in a string without overflow?