// Float64bits returns the IEEE 754 binary representation of f. //func Float64bits(f float64) uint64 { return *(*uint64)(unsafe.Pointer(&f)) } func Float64bits(f float64) uint64 { if hx.GetBool("", "Object.nativeFloats") { var t float64 = f return *(*uint64)(unsafe.Pointer(&t)) } switch runtime.GOARCH { case "cs": return uint64(hx.Int64(hx.CallDynamic("", "Force.Float64bits", 1, f))) // TODO js/cpp/neko short-cut - using Force.f64byts //case "js", "cpp", "neko": // return uint64(hx.Int64(hx.CallDynamic("", "Force.Float64bits", 1, f))) } // below from math.IsInf if f > MaxFloat64 { return uvinf } if f < -MaxFloat64 { return uvneginf } if f != f { // NaN if f < 0 { // -NaN ? return uvnan | uint64(1)<<63 } //return 9221120237041090561 return uvnan } if f == 0 { if 1/f < -MaxFloat64 { // dividing by -0 gives -Inf return uint64(1) << 63 } return 0 } s := uint64(0) if f < hx.GetFloat("", "0") { s = 1 << 63 f = -f } e := uint32(1023 + 52) for f >= float64(int64(1<<53)) { f /= hx.GetFloat("", "2") e++ if e == uint32((1<<11)-1) { break } } for f < float64(int64(1<<52)) { e-- if e == 0 { break } f *= hx.GetFloat("", "2") } return s | uint64(e)<<52 | (uint64(f) &^ (1 << 52)) }
// Float64frombits returns the floating point number corresponding // the IEEE 754 binary representation b. //func Float64frombits(b uint64) float64 { return *(*float64)(unsafe.Pointer(&b)) } func Float64frombits(b uint64) float64 { if hx.GetBool("", "Object.nativeFloats") { var t uint64 = b return *(*float64)(unsafe.Pointer(&t)) } switch runtime.GOARCH { case "cs": return hx.CallFloat("", "Force.Float64frombits", 1, b) // TODO js/cpp/neko short-cut //case "js", "cpp", "neko": // return hx.CallFloat("", "Force.Float64frombits", 1, b) } // first handle the special cases switch b { case uvnan: return nan case uvnan | 1<<63: return nan * -1 // -NaN case uvinf: return posInf case uvneginf: return negInf case 0: return 0 case 1 << 63: return zero * -1 // -0 } // below from GopherJS s := hx.GetFloat("", "1") if b&(1<<63) != 0 { s = hx.GetFloat("", "-1") } e := (b >> 52) & uint64((1<<11)-1) m := b & uint64((1<<52)-1) if e == uint64((1<<11)-1) { if m == 0 { return s / hx.GetFloat("", "0") } return nan } if e != 0 { m += 1 << 52 } if e == 0 { e = 1 } return Ldexp(float64(m), int(e)-1023-52) * s }
func (f *randomFile) pread(b []byte, offset int64) (int, error) { //return naclRead(f.naclFD, b) for i := range b { b[i] = byte(hx.GetFloat("", "Math.random()") * 256.0) } return len(b), nil }
// Modf returns integer and fractional floating-point numbers // that sum to f. Both values have the same sign as f. // // Special cases are: // Modf(±Inf) = ±Inf, NaN // Modf(NaN) = NaN, NaN func Modf(f float64) (int float64, frac float64) { // approach inspired by GopherJS, see that project for copyright etc //if f == posInf || f == negInf { if !hx.CallBool("", "Math.isFinite", 1, f) { return f, hx.GetFloat("", "Math.NaN") } frac = Mod(f, 1) return f - frac, frac }
func testFloatConv() { if runtime.GOARCH != "neko" { TEQ("SmallestNormalFloat64", SmallestNormalFloat64, tc64(SmallestNormalFloat64)) TEQ("LargestSubnormalFloat64", LargestSubnormalFloat64, tc64(LargestSubnormalFloat64)) TEQ("MaxFloat32", MaxFloat32, tc64(MaxFloat32)) TEQ("SmallestNonzeroFloat32", SmallestNonzeroFloat32, tc64(SmallestNonzeroFloat32)) TEQ("MaxFloat64", MaxFloat64, tc64(MaxFloat64)) TEQ("SmallestNonzeroFloat64", SmallestNonzeroFloat64, tc64(SmallestNonzeroFloat64)) TEQ("42.42", 42.42, tc64(42.42)) if runtime.GOOS == "nacl" { pi := tc64(hx.GetFloat("", "Math.POSITIVE_INFINITY")) if pi <= MaxFloat64 { fmt.Println("testFloatConv() POSITIVE_INFINITY invalid") } ni := tc64(hx.GetFloat("", "Math.NEGATIVE_INFINITY")) if ni >= SmallestNonzeroFloat64 { fmt.Println("testFloatConv() NEGATIVE_INFINITY invalid") } if hx.GetFloat("", "Math.NaN") == tc64(hx.GetFloat("", "Math.NaN")) { fmt.Println("testFloatConv() NaN == NaN") } } } }
// Provided by package runtime. func now() (sec int64, nsec int32) { haxeNow := hx.GetFloat("", "Date.now().getTime()") // milliseconds secFloat := hx.CallFloat("", "Math.ffloor", 1, haxeNow/1000) return int64(secFloat), int32(1000000000 * ((haxeNow / 1000) - secFloat)) }
// Provided by package runtime. func now() (sec int64, nsec int32) { haxeNow := hx.GetFloat("", "Date.now().getTime()") secFloat := hx.CallFloat("", "Math.ffloor", 1, haxeNow) return int64(secFloat), int32(1000000000 * (haxeNow - secFloat)) }
// Float32bits returns the IEEE 754 binary representation of f. //func Float32bits(f float32) uint32 { return *(*uint32)(unsafe.Pointer(&f)) } func Float32bits(f float32) uint32 { // stop recursion - NOTE also must not compare two float32 in this fn ! if InF32fb { panic("haxegoruntime.Float32bits() InF32fb already set") } InF32fb = true defer func() { InF32fb = false }() if hx.GetBool("", "Object.nativeFloats") { var t float32 = f return *(*uint32)(unsafe.Pointer(&t)) } // TODO cpp/neko/js short-cut /* switch runtime.GOARCH { case "cpp", "neko", "js": return uint32(hx.CallInt("", "Force.Float32bits", 1, f)) } */ // below logic from math.IsInf if float64(f) > float64(MaxFloat32) { return uvinf32 } if float64(f) < float64(-MaxFloat32) { return uvneginf32 } if float64(f) != float64(f) { // NaN if float64(f) < 0 { // -NaN ? return uvnan32 | uint32(1)<<31 } return uvnan32 } if float64(f) == 0 { if 1/float64(f) < float64(-MaxFloat32) { // dividing by -0 gives -Inf return uint32(1) << 31 } return 0 } s := uint32(0) if float64(f) < 0 { // must use float64 to avoid recusion on the comparison NOTE ditto below... s = 1 << 31 f = -f } e := uint32(127 + 23) for float64(f) >= 1<<24 { f /= 2 e++ if e == uint32((1<<8)-1) { if float64(f) >= 1<<23 { f = float32(posInf) } break } } for float64(f) < float64(1<<23) { e-- if e == 0 { break } f *= 2 } //r := js.Global.Call("$mod", f, 2).Float() // below is code to simulate: r := mth.Mod(float64(f), 2) if float64(f) < hx.GetFloat("", "0") { panic("haxegoruntime.Float32bits") } t := float64(f) / 2 r := float64(f) - (2 * t) // end simulate code if (r > hx.GetFloat("", "0.5") && r < hx.GetFloat("", "1")) || r >= hx.GetFloat("", "1.5") { // round to nearest even f++ } return s | uint32(e)<<23 | (uint32(f) &^ (1 << 23)) }