@@ -209,6 +209,12 @@ func alike32(x, y float32) bool {
209209
210210}
211211
212+ func alike64 (x , y float64 ) bool {
213+ // we can ignore NaNs
214+ return x == y && math .Signbit (x ) == math .Signbit (y )
215+
216+ }
217+
212218func TestFloatMantExp (t * testing.T ) {
213219 for _ , test := range []struct {
214220 x string
@@ -908,35 +914,37 @@ func TestFloatFloat64(t *testing.T) {
908914 out float64
909915 acc Accuracy
910916 }{
911- {"-Inf" , math .Inf (- 1 ), Exact },
912- {"-0x1.fffffffffffff8p2147483646" , - math .Inf (+ 1 ), Below }, // overflow in rounding
913- {"-1e10000" , math .Inf (- 1 ), Below }, // overflow
914- {"-0x1p1024" , math .Inf (- 1 ), Below }, // overflow
915- {"-0x1.fffffffffffff8p1023" , - math .Inf (+ 1 ), Below }, // overflow
916- {"-0x1.fffffffffffff4p1023" , - math .MaxFloat64 , Above },
917- {"-0x1.fffffffffffff0p1023" , - math .MaxFloat64 , Exact },
918- {"-12345.000000000000000000001" , - 12345 , Above },
919- {"-12345.0" , - 12345 , Exact },
920- {"-1.000000000000000000001" , - 1 , Above },
921- {"-1" , - 1 , Exact },
922- {"-0x0.0000000000001p-1022" , - math .SmallestNonzeroFloat64 , Exact },
923- {"-0x0.0000000000001p-1023" , - 0 , Above }, // underflow
924- {"-1e-1000" , - 0 , Above }, // underflow
925917 {"0" , 0 , Exact },
926- {"1e-1000" , 0 , Below }, // underflow
927- {"0x0.0000000000001p-1023" , 0 , Below }, // underflow
928- {"0x0.0000000000001p-1022" , math .SmallestNonzeroFloat64 , Exact },
918+
919+ // underflow
920+ {"1e-1000" , 0 , Below },
921+ {"0x0.0000000000001p-1023" , 0 , Below },
922+ {"0x0.00000000000008p-1022" , 0 , Below },
923+
924+ // denormals
925+ // TODO(gri) enable once Float64 is fixed
926+ // {"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal
927+ {"0x0.0000000000001p-1022" , math .SmallestNonzeroFloat64 , Exact }, // smallest denormal
928+ {"0x.8p-1073" , math .SmallestNonzeroFloat64 , Exact },
929+ {"1p-1074" , math .SmallestNonzeroFloat64 , Exact },
930+ {"0x.fffffffffffffp-1022" , math .Float64frombits (0x000fffffffffffff ), Exact }, // largest denormal
931+
932+ // normals
933+ {"0x.fffffffffffff8p-1022" , math .Float64frombits (0x0010000000000000 ), Above }, // rounded up to smallest normal
934+ {"1p-1022" , math .Float64frombits (0x0010000000000000 ), Exact }, // smallest normal
929935 {"1" , 1 , Exact },
930936 {"1.000000000000000000001" , 1 , Below },
931937 {"12345.0" , 12345 , Exact },
932938 {"12345.000000000000000000001" , 12345 , Below },
933939 {"0x1.fffffffffffff0p1023" , math .MaxFloat64 , Exact },
934940 {"0x1.fffffffffffff4p1023" , math .MaxFloat64 , Below },
935- {"0x1.fffffffffffff8p1023" , math .Inf (+ 1 ), Above }, // overflow
936- {"0x1p1024" , math .Inf (+ 1 ), Above }, // overflow
937- {"1e10000" , math .Inf (+ 1 ), Above }, // overflow
941+
942+ // overflow
943+ {"0x1.fffffffffffff8p1023" , math .Inf (+ 1 ), Above },
944+ {"0x1p1024" , math .Inf (+ 1 ), Above },
945+ {"1e10000" , math .Inf (+ 1 ), Above },
938946 {"0x1.fffffffffffff8p2147483646" , math .Inf (+ 1 ), Above }, // overflow in rounding
939- {"+ Inf" , math .Inf (+ 1 ), Exact },
947+ {"Inf" , math .Inf (+ 1 ), Exact },
940948
941949 // selected denormalized values that were handled incorrectly in the past
942950 {"0x.fffffffffffffp-1022" , smallestNormalFloat64 - math .SmallestNonzeroFloat64 , Exact },
@@ -947,22 +955,32 @@ func TestFloatFloat64(t *testing.T) {
947955 // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
948956 {"2.2250738585072012e-308" , 2.2250738585072014e-308 , Above },
949957 } {
950- // conversion should match strconv where syntax is agreeable
951- if f , err := strconv .ParseFloat (test .x , 64 ); err == nil && f != test .out {
952- t .Errorf ("%s: got %g; want %g (incorrect test data)" , test .x , f , test .out )
953- }
958+ for i := 0 ; i < 2 ; i ++ {
959+ // test both signs
960+ tx , tout , tacc := test .x , test .out , test .acc
961+ if i != 0 {
962+ tx = "-" + tx
963+ tout = - tout
964+ tacc = - tacc
965+ }
954966
955- x := makeFloat (test .x )
956- out , acc := x .Float64 ()
957- if out != test .out || acc != test .acc {
958- t .Errorf ("%s: got %g (%#x, %s); want %g (%#x, %s)" , test .x , out , math .Float64bits (out ), acc , test .out , math .Float64bits (test .out ), test .acc )
959- }
967+ // conversion should match strconv where syntax is agreeable
968+ if f , err := strconv .ParseFloat (tx , 64 ); err == nil && ! alike64 (f , tout ) {
969+ t .Errorf ("%s: got %g; want %g (incorrect test data)" , tx , f , tout )
970+ }
960971
961- // test that x.SetFloat64(f).Float64() == f
962- var x2 Float
963- out2 , acc2 := x2 .SetFloat64 (out ).Float64 ()
964- if out2 != out || acc2 != Exact {
965- t .Errorf ("idempotency test: got %g (%s); want %g (Exact)" , out2 , acc2 , out )
972+ x := makeFloat (tx )
973+ out , acc := x .Float64 ()
974+ if ! alike64 (out , tout ) || acc != tacc {
975+ t .Errorf ("%s: got %g (%#x, %s); want %g (%#x, %s)" , tx , out , math .Float64bits (out ), acc , test .out , math .Float64bits (test .out ), tacc )
976+ }
977+
978+ // test that x.SetFloat64(f).Float64() == f
979+ var x2 Float
980+ out2 , acc2 := x2 .SetFloat64 (out ).Float64 ()
981+ if ! alike64 (out2 , out ) || acc2 != Exact {
982+ t .Errorf ("idempotency test: got %g (%s); want %g (Exact)" , out2 , acc2 , out )
983+ }
966984 }
967985 }
968986}
0 commit comments