main.mx raw

   1  // Untyped float constants are exact rationals, not rounded float64s - in one
   2  // package and across the .mxh boundary.
   3  //
   4  // stage4 compared `constEqual`'s rounded float64, and exported a folded
   5  // constant as its shortest round-tripping decimal. Both made
   6  // `math.MaxFloat64 == 1.7976931348623157e308` true: the decimal rounds to the
   7  // binary value, so the two constants were indistinguishable after rounding.
   8  // go/types (the legacy compiler) compares the exact rationals and says false.
   9  package main
  10  
  11  import (
  12  	"fmt"
  13  	"math"
  14  )
  15  
  16  // The exact expression, in-package: 2^1023 * (1 + (1 - 2^-52)).
  17  const maxExpr = 0x1p1023 * (1 + (1 - 0x1p-52))
  18  
  19  func main() {
  20  	// Across packages: the exported constant carries its exact value, so the
  21  	// decimal that merely rounds to it is a different number.
  22  	if math.MaxFloat64 == 1.7976931348623157e308 {
  23  		panic("math.MaxFloat64 equals the decimal that rounds to it")
  24  	}
  25  	if !(math.MaxFloat64 == 0x1p1023*(1+(1-0x1p-52))) {
  26  		panic("math.MaxFloat64 is not the value of its exact expression")
  27  	}
  28  	// The same two comparisons from inside the defining package.
  29  	if maxExpr == 1.7976931348623157e308 {
  30  		panic("the exact expression equals the decimal that rounds to it")
  31  	}
  32  	if !(maxExpr == 0x1p1023*(1+(1-0x1p-52))) {
  33  		panic("identical expressions are not equal")
  34  	}
  35  	// Constant arithmetic is exact, so these follow go/types, not float64:
  36  	// 0.1+0.2 is 3/10 exactly, and 1/3 is not the 16-digit decimal.
  37  	if !(0.1+0.2 == 0.3) {
  38  		panic("0.1+0.2 must equal 0.3 exactly")
  39  	}
  40  	if 1.0/3.0 == 0.3333333333333333 {
  41  		panic("1/3 must not equal the 16-digit decimal")
  42  	}
  43  	if !(1.0/3.0*3.0 == 1.0) {
  44  		panic("1/3*3 must equal 1 exactly")
  45  	}
  46  	if math.MaxFloat64/2 == math.MaxFloat64 {
  47  		panic("MaxFloat64/2 is not MaxFloat64")
  48  	}
  49  	fmt.Println("ok")
  50  }
  51