// 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 ...any) {
	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
}
