有时候,我们在 Golang 中会错误地将
float64
直接转换为 int32
raw = 529538871408
fv = float64(raw)
fmt.Println(raw)
fmt.Println(fv)
fmt.Println(int32(fv))
输出
529538871408
5.29538871408e+11
-2147483648
为什么
int32(fv)
给出负数?
众所周知,C++中的
long
和Golang中的float64
都是64位IEEE 754双精度。所以我们在 C++ 中尝试相同的代码
int64_t iv = 529538871408;
std::cout << iv << std::endl;
double fv = double(iv);
std::cout << fv << std::endl;
int32_t i32v = int32_t(fv);
std::cout << i32v << std::endl;
输出:
529538871408
5.29539e+11
2147483647
结果是
2147483647
,为什么呢?我有什么遗漏吗?或者有什么问题吗?
在 go 中你可以溢出到符号位
package main
import (
"fmt"
)
func main() {
a, b := int32(2147483647), int32(1)
c := a + b
fmt.Printf("%d %T", c, c)
}
您的操作系统和编译器是什么?我使用的是gcc版本10.3.0(Ubuntu 10.3.0-1ubuntu1~20.10),结果也是负数。
回到主题,溢出行为在大多数编程语言中通常是未定义的行为,并且同一语言的不同编译器实现可能会产生不同的效果。
#include<iostream>
using namespace std;
int main()
{
int64_t iv = 529538871408;
std::cout << iv << std::endl;
double fv = double(iv);
std::cout << fv << std::endl;
int32_t i32v = int32_t(fv);
std::cout << i32v << std::endl;
return 0;
}
/*
Output
529538871408
5.29539e+11
-2147483648
/*