-2

Occasionally, we cast float64 to int32 directly by mistake in Golang

    raw = 529538871408
    fv = float64(raw)

    fmt.Println(raw)
    fmt.Println(fv)
    fmt.Println(int32(fv))

Output

529538871408
5.29538871408e+11
-2147483648       

Why int32(fv) given a negative number?

As we know, both long in C++ and float64 in Golang is a 64 bit IEEE 754 double precision. So we try same code in 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;

Output:

529538871408
5.29539e+11
2147483647

The result is 2147483647, why? Is anything am I missing? or something wrong?

user207421
  • 305,947
  • 44
  • 307
  • 483
zangw
  • 43,869
  • 19
  • 177
  • 214
  • 5
    I have no knowledge about `golang` but `int32` implies a number in the range `[-2147483648, 2147483647]` (two's compliment). 529538871408 > 2^31 so, overflow. Signed overflows may be ok in `golang` but they are not in C++ (until C++20). – Ted Lyngmo Jun 12 '20 at 05:17
  • "Why int32(fv) given a negative number?" Because the language spec says it must. – Volker Jun 12 '20 at 08:16
  • 1
    You're doing something unspecified in Go: ["In all non-constant conversions involving floating-point or complex values, if the result type cannot represent the value the conversion succeeds but the result value is implementation-dependent."](https://golang.org/ref/spec#Conversions) – Peter Jun 12 '20 at 09:25
  • @Volker, could you please me the link of the language spec? – zangw Jun 12 '20 at 09:30

1 Answers1

3

In go you can overflow to the sign bit

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

Shubham Srivastava
  • 1,807
  • 1
  • 10
  • 17