0

I've been testing a few things in Go, and noticed integers can overflow, but float64 and float32 apparently can't.

f64 := math.MaxFloat64
fmt.Printf("%f\n", f64)
fmt.Printf("%f\n", f64+1)

f32 := math.MaxFloat32
fmt.Printf("%f\n", f32)
fmt.Printf("%f\n", f32+1)

i := math.MaxInt64
fmt.Printf("%d\n", i)
fmt.Printf("%d\n", i+1)

Result:

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000
340282346638528859811704183484516925440.000000
340282346638528859811704183484516925440.000000
9223372036854775807
-9223372036854775808

Integer overflows are apparently not checked for performance reasons, but why can't I make floats overflow? Are they checked?

SystemGlitch
  • 2,150
  • 12
  • 27
  • To a certain degree floats do "overflow". Try e.g. `math.Pow10(100)`. Or `math.Sqrt(-4)`. They just do not wrap around. – Volker Aug 11 '20 at 13:30
  • 1
    The precision for floats at the upper bound is nowhere near enough to represent "one more". Try doubling the numbers: https://play.golang.org/p/Ve6MO0FFHNA – Peter Aug 11 '20 at 14:37
  • Knowing the basics of IEEE-754 is essentially required knowledge for most programmers. For example: https://stackoverflow.com/q/588004/32880 and see https://floating-point-gui.de/ as well – JimB Aug 11 '20 at 17:42

1 Answers1

6

Because the data structures are fundamentally different. The two's complement structure used by most programming languages (including Go) for (at least most of) their integral data types overflows as a by-product of how it works; the IEEE-754 floating point used by most programming languages (including Go) for (at least most of) their floating point data types doesn't overflow, the way it works the magnitude of the number just continues to increase and, once it's past a certain point, the number starts losing precision even at the integer level.

It's just that the two mechanisms for storing numeric data in a fixed-size set of bits work fundamentally differently.

There are other structures. For instance, some languages have "big integer" and/or "big decimal" types that aren't fixed size; instead, they take up however much room they need to hold the number. (Java's BigInteger and BigDecimal, JavaScript's BigInt, ...) Go has Int, Rat, and Float in the math/big package. (Thanks Adrian!) The fixed-size ones are very useful because they're very fast; but sometimes you want something other than speed (extended range, better precision in floating point, etc.), in which case you sacrifice some speed for the other thing you need.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875