为什么在Go语言中将float64转换为int32会给予一个负数?

qmelpv7a  于 12个月前  发布在  Go
关注(0)|答案(2)|浏览(143)

偶尔,我们会在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,为什么?我错过了什么吗?还是出了什么问题

knsnq2tg

knsnq2tg1#

在go中你可以溢出到符号位

package main

import (
    "fmt"
)

func main() {
    a, b := int32(2147483647), int32(1)
    c := a + b
    fmt.Printf("%d %T", c, c)
}

check it out on playground

crcmnpdw

crcmnpdw2#

你的操作系统和编译器是什么?我使用的是gcc版本10.3.0(Ubuntu 10.3.0- 1ubuntu 1 ~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
/*

相关问题