// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime_test

import (
	"math"
	"math/rand"
	. "runtime"
	"testing"
)

// turn uint64 op into float64 op
func fop(f func(x, y uint64) uint64) func(x, y float64) float64 {
	return func(x, y float64) float64 {
		bx := math.Float64bits(x)
		by := math.Float64bits(y)
		return math.Float64frombits(f(bx, by))
	}
}

func add(x, y float64) float64 { return x + y }
func sub(x, y float64) float64 { return x - y }
func mul(x, y float64) float64 { return x * y }
func div(x, y float64) float64 { return x / y }

func TestFloat64(t *testing.T) {
	base := []float64{
		0,
		math.Copysign(0, -1),
		-1,
		1,
		math.NaN(),
		math.Inf(+1),
		math.Inf(-1),
		0.1,
		1.5,
		1.9999999999999998,     // all 1s mantissa
		1.3333333333333333,     // 1.010101010101...
		1.1428571428571428,     // 1.001001001001...
		1.112536929253601e-308, // first normal
		2,
		4,
		8,
		16,
		32,
		64,
		128,
		256,
		3,
		12,
		1234,
		123456,
		-0.1,
		-1.5,
		-1.9999999999999998,
		-1.3333333333333333,
		-1.1428571428571428,
		-2,
		-3,
		1e-200,
		1e-300,
		1e-310,
		5e-324,
		1e-105,
		1e-305,
		1e+200,
		1e+306,
		1e+307,
		1e+308,
	}
	all := make([]float64, 200)
	copy(all, base)
	for i := len(base); i < len(all); i++ {
		all[i] = rand.NormFloat64()
	}

	test(t, "+", add, fop(Fadd64), all)
	test(t, "-", sub, fop(Fsub64), all)
	if GOARCH != "386" { // 386 is not precise!
		test(t, "*", mul, fop(Fmul64), all)
		test(t, "/", div, fop(Fdiv64), all)
	}
}

// 64 -hw-> 32 -hw-> 64
func trunc32(f float64) float64 {
	return float64(float32(f))
}

// 64 -sw->32 -hw-> 64
func to32sw(f float64) float64 {
	return float64(math.Float32frombits(F64to32(math.Float64bits(f))))
}

// 64 -hw->32 -sw-> 64
func to64sw(f float64) float64 {
	return math.Float64frombits(F32to64(math.Float32bits(float32(f))))
}

// float64 -hw-> int64 -hw-> float64
func hwint64(f float64) float64 {
	return float64(int64(f))
}

// float64 -hw-> int32 -hw-> float64
func hwint32(f float64) float64 {
	return float64(int32(f))
}

// float64 -sw-> int64 -hw-> float64
func toint64sw(f float64) float64 {
	i, ok := F64toint(math.Float64bits(f))
	if !ok {
		// There's no right answer for out of range.
		// Match the hardware to pass the test.
		i = int64(f)
	}
	return float64(i)
}

// float64 -hw-> int64 -sw-> float64
func fromint64sw(f float64) float64 {
	return math.Float64frombits(Fintto64(int64(f)))
}

var nerr int

func err(t *testing.T, format string, args ...interface{}) {
	t.Errorf(format, args...)

	// cut errors off after a while.
	// otherwise we spend all our time
	// allocating memory to hold the
	// formatted output.
	if nerr++; nerr >= 10 {
		t.Fatal("too many errors")
	}
}

func test(t *testing.T, op string, hw, sw func(float64, float64) float64, all []float64) {
	for _, f := range all {
		for _, g := range all {
			h := hw(f, g)
			s := sw(f, g)
			if !same(h, s) {
				err(t, "%g %s %g = sw %g, hw %g\n", f, op, g, s, h)
			}
			testu(t, "to32", trunc32, to32sw, h)
			testu(t, "to64", trunc32, to64sw, h)
			testu(t, "toint64", hwint64, toint64sw, h)
			testu(t, "fromint64", hwint64, fromint64sw, h)
			testcmp(t, f, h)
			testcmp(t, h, f)
			testcmp(t, g, h)
			testcmp(t, h, g)
		}
	}
}

func testu(t *testing.T, op string, hw, sw func(float64) float64, v float64) {
	h := hw(v)
	s := sw(v)
	if !same(h, s) {
		err(t, "%s %g = sw %g, hw %g\n", op, v, s, h)
	}
}

func hwcmp(f, g float64) (cmp int, isnan bool) {
	switch {
	case f < g:
		return -1, false
	case f > g:
		return +1, false
	case f == g:
		return 0, false
	}
	return 0, true // must be NaN
}

func testcmp(t *testing.T, f, g float64) {
	hcmp, hisnan := hwcmp(f, g)
	scmp, sisnan := Fcmp64(math.Float64bits(f), math.Float64bits(g))
	if int32(hcmp) != scmp || hisnan != sisnan {
		err(t, "cmp(%g, %g) = sw %v, %v, hw %v, %v\n", f, g, scmp, sisnan, hcmp, hisnan)
	}
}

func same(f, g float64) bool {
	if math.IsNaN(f) && math.IsNaN(g) {
		return true
	}
	if math.Copysign(1, f) != math.Copysign(1, g) {
		return false
	}
	return f == g
}
