/**********************************************************************
*
* Float to string Test
*
**********************************************************************/
module ftoa
import math

union Ufloat32 {
mut:
	f f32 = f32(0)
	b u32
}

union Ufloat64 {
mut:
	f f64 = f64(0)
	b u64
}

fn f64_from_bits1(b u64) f64 {
	mut x := Ufloat64{}
	x.b = b
	//C.printf("bin: %016llx\n",x.f)
	return x.f
}

fn f32_from_bits1(b u32) f32 {
	mut x := Ufloat32{}
	x.b = b
	//C.printf("bin: %08x\n",x.f)
	return x.f
}

const(
test_cases_f32 = [
	f32_from_bits1(0x0000_0000), // +0
	f32_from_bits1(0x8000_0000), // -0
	f32_from_bits1(0xFFC0_0001), // sNan
	f32_from_bits1(0xFF80_0001), // qNan
	f32_from_bits1(0x7F80_0000), // +inf
	f32_from_bits1(0xFF80_0000), // -inf
	1,
	-1,
	10,
	-10,
	0.3,
	-0.3,
	1000000,
	123456.7,
	123e35,
	-123.45,
	1e23,
	f32_from_bits1(0x0080_0000), // smallest float32
	math.max_f32,
	383260575764816448,
]

exp_result_f32 = [
	"0e+00",
	"-0e+00",
	"nan",
	"nan",
	"+inf",
	"-inf",
	"1.e+00",
	"-1.e+00",
	"1.e+01",
	"-1.e+01",
	"3.e-01",
	"-3.e-01",
	"1.e+06",
	"1.234567e+05",
	"1.23e+37",
	"-1.2345e+02",
	"1.e+23",
	"1.1754944e-38", // aprox from 1.1754943508 × 10−38, 
	"3.4028235e+38",
	"3.8326058e+17",
]

test_cases_f64 = [
	f64_from_bits1(0x0000_0000_0000_0000), // +0
	f64_from_bits1(0x8000_0000_0000_0000), // -0
	f64_from_bits1(0x7FF0_0000_0000_0001), // sNan
	f64_from_bits1(0x7FF8_0000_0000_0001), // qNan
	f64_from_bits1(0x7FF0_0000_0000_0000), // +inf
	f64_from_bits1(0xFFF0_0000_0000_0000), // -inf
	1,
	-1,
	10,
	-10,
	0.3,
	-0.3,
	1000000,
	123456.7,
	123e45,
	-123.45,
	1e23,
	f64_from_bits1(0x0010_0000_0000_0000), // smallest float64
	math.max_f32,
	383260575764816448,
	383260575764816448,
	// C failing cases
	123e300,
	123e-300,
	5.e-324,
	-5.e-324,
]

exp_result_f64 = [
	"0e+00",
	"-0e+00",
	"nan",
	"nan",
	"+inf",
	"-inf",
	"1.e+00",
	"-1.e+00",
	"1.e+01",
	"-1.e+01",
	"3.e-01",
	"-3.e-01",
	"1.e+06",
	"1.234567e+05",
	"1.23e+47",
	"-1.2345e+02",
	"1.e+23",
	"2.2250738585072014e-308",
	"3.4028234663852886e+38",
	"3.8326057576481645e+17",
	"3.8326057576481645e+17",

	"1.23e+302", // this test is failed from C sprintf!!
	"1.23e-298",
	"5.e-324",
	"-5.e-324",
]
)

fn test_float_to_str(){
	// test f32
	for c,x in test_cases_f32 {
		s  := f32_to_str(x,8)
		s1 := exp_result_f32[c]
		//println("$s1 $s")
		assert s == s1
	}

	// test f64
	for c,x in test_cases_f64 {
		s  := f64_to_str(x,17)
		s1 := exp_result_f64[c]
		//println("$s1 $s")
		assert s == s1
	}

	// test long format
	for exp := 1 ; exp < 120 ; exp++ {
		a := f64_to_str_l(("1e"+exp.str()).f64())
		//println(a)
		assert a.len == exp + 1

		b := f64_to_str_l(("1e-"+exp.str()).f64())
		//println(b)
		assert b.len == exp + 2
	}
}