Source file 
src/runtime/softfloat64_test.go
     1  
     2  
     3  
     4  
     5  package runtime_test
     6  
     7  import (
     8  	"math"
     9  	"math/rand"
    10  	. "runtime"
    11  	"testing"
    12  )
    13  
    14  
    15  func fop(f func(x, y uint64) uint64) func(x, y float64) float64 {
    16  	return func(x, y float64) float64 {
    17  		bx := math.Float64bits(x)
    18  		by := math.Float64bits(y)
    19  		return math.Float64frombits(f(bx, by))
    20  	}
    21  }
    22  
    23  func add(x, y float64) float64 { return x + y }
    24  func sub(x, y float64) float64 { return x - y }
    25  func mul(x, y float64) float64 { return x * y }
    26  func div(x, y float64) float64 { return x / y }
    27  
    28  func TestFloat64(t *testing.T) {
    29  	base := []float64{
    30  		0,
    31  		math.Copysign(0, -1),
    32  		-1,
    33  		1,
    34  		math.NaN(),
    35  		math.Inf(+1),
    36  		math.Inf(-1),
    37  		0.1,
    38  		1.5,
    39  		1.9999999999999998,     
    40  		1.3333333333333333,     
    41  		1.1428571428571428,     
    42  		1.112536929253601e-308, 
    43  		2,
    44  		4,
    45  		8,
    46  		16,
    47  		32,
    48  		64,
    49  		128,
    50  		256,
    51  		3,
    52  		12,
    53  		1234,
    54  		123456,
    55  		-0.1,
    56  		-1.5,
    57  		-1.9999999999999998,
    58  		-1.3333333333333333,
    59  		-1.1428571428571428,
    60  		-2,
    61  		-3,
    62  		1e-200,
    63  		1e-300,
    64  		1e-310,
    65  		5e-324,
    66  		1e-105,
    67  		1e-305,
    68  		1e+200,
    69  		1e+306,
    70  		1e+307,
    71  		1e+308,
    72  	}
    73  	all := make([]float64, 200)
    74  	copy(all, base)
    75  	for i := len(base); i < len(all); i++ {
    76  		all[i] = rand.NormFloat64()
    77  	}
    78  
    79  	test(t, "+", add, fop(Fadd64), all)
    80  	test(t, "-", sub, fop(Fsub64), all)
    81  	if GOARCH != "386" { 
    82  		test(t, "*", mul, fop(Fmul64), all)
    83  		test(t, "/", div, fop(Fdiv64), all)
    84  	}
    85  }
    86  
    87  
    88  func trunc32(f float64) float64 {
    89  	return float64(float32(f))
    90  }
    91  
    92  
    93  func to32sw(f float64) float64 {
    94  	return float64(math.Float32frombits(F64to32(math.Float64bits(f))))
    95  }
    96  
    97  
    98  func to64sw(f float64) float64 {
    99  	return math.Float64frombits(F32to64(math.Float32bits(float32(f))))
   100  }
   101  
   102  
   103  func hwint64(f float64) float64 {
   104  	return float64(int64(f))
   105  }
   106  
   107  
   108  func hwint32(f float64) float64 {
   109  	return float64(int32(f))
   110  }
   111  
   112  
   113  func toint64sw(f float64) float64 {
   114  	i, ok := F64toint(math.Float64bits(f))
   115  	if !ok {
   116  		
   117  		
   118  		i = int64(f)
   119  	}
   120  	return float64(i)
   121  }
   122  
   123  
   124  func fromint64sw(f float64) float64 {
   125  	return math.Float64frombits(Fintto64(int64(f)))
   126  }
   127  
   128  var nerr int
   129  
   130  func err(t *testing.T, format string, args ...any) {
   131  	t.Errorf(format, args...)
   132  
   133  	
   134  	
   135  	
   136  	
   137  	if nerr++; nerr >= 10 {
   138  		t.Fatal("too many errors")
   139  	}
   140  }
   141  
   142  func test(t *testing.T, op string, hw, sw func(float64, float64) float64, all []float64) {
   143  	for _, f := range all {
   144  		for _, g := range all {
   145  			h := hw(f, g)
   146  			s := sw(f, g)
   147  			if !same(h, s) {
   148  				err(t, "%g %s %g = sw %g, hw %g\n", f, op, g, s, h)
   149  			}
   150  			testu(t, "to32", trunc32, to32sw, h)
   151  			testu(t, "to64", trunc32, to64sw, h)
   152  			testu(t, "toint64", hwint64, toint64sw, h)
   153  			testu(t, "fromint64", hwint64, fromint64sw, h)
   154  			testcmp(t, f, h)
   155  			testcmp(t, h, f)
   156  			testcmp(t, g, h)
   157  			testcmp(t, h, g)
   158  		}
   159  	}
   160  }
   161  
   162  func testu(t *testing.T, op string, hw, sw func(float64) float64, v float64) {
   163  	h := hw(v)
   164  	s := sw(v)
   165  	if !same(h, s) {
   166  		err(t, "%s %g = sw %g, hw %g\n", op, v, s, h)
   167  	}
   168  }
   169  
   170  func hwcmp(f, g float64) (cmp int, isnan bool) {
   171  	switch {
   172  	case f < g:
   173  		return -1, false
   174  	case f > g:
   175  		return +1, false
   176  	case f == g:
   177  		return 0, false
   178  	}
   179  	return 0, true 
   180  }
   181  
   182  func testcmp(t *testing.T, f, g float64) {
   183  	hcmp, hisnan := hwcmp(f, g)
   184  	scmp, sisnan := Fcmp64(math.Float64bits(f), math.Float64bits(g))
   185  	if int32(hcmp) != scmp || hisnan != sisnan {
   186  		err(t, "cmp(%g, %g) = sw %v, %v, hw %v, %v\n", f, g, scmp, sisnan, hcmp, hisnan)
   187  	}
   188  }
   189  
   190  func same(f, g float64) bool {
   191  	if math.IsNaN(f) && math.IsNaN(g) {
   192  		return true
   193  	}
   194  	if math.Copysign(1, f) != math.Copysign(1, g) {
   195  		return false
   196  	}
   197  	return f == g
   198  }
   199  
View as plain text