Beispiel #1
0
// 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))
}
Beispiel #2
0
// 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
}
Beispiel #3
0
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
}
Beispiel #4
0
// 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
}
Beispiel #5
0
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")
			}
		}
	}
}
Beispiel #6
0
// 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))
}
Beispiel #7
0
// 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))
}
Beispiel #8
0
// 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))
}