gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/state/tests/float_test.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tests
    16  
    17  import (
    18  	"math"
    19  	"testing"
    20  )
    21  
    22  var safeFloat32s = []float32{
    23  	float32(0.0),
    24  	float32(1.0),
    25  	float32(-1.0),
    26  	float32(math.Inf(1)),
    27  	float32(math.Inf(-1)),
    28  }
    29  
    30  var allFloat32s = append(safeFloat32s, float32(math.NaN()))
    31  
    32  var safeFloat64s = []float64{
    33  	float64(0.0),
    34  	float64(1.0),
    35  	float64(-1.0),
    36  	math.Inf(1),
    37  	math.Inf(-1),
    38  }
    39  
    40  var allFloat64s = append(safeFloat64s, math.NaN())
    41  
    42  func TestFloat(t *testing.T) {
    43  	runTestCases(t, false, "plain", flatten(
    44  		allFloat32s,
    45  		allFloat64s,
    46  	))
    47  	// See checkEqual for why NaNs are missing.
    48  	runTestCases(t, false, "pointers", pointersTo(flatten(
    49  		safeFloat32s,
    50  		safeFloat64s,
    51  	)))
    52  	runTestCases(t, false, "interfaces", interfacesTo(flatten(
    53  		safeFloat32s,
    54  		safeFloat64s,
    55  	)))
    56  	runTestCases(t, false, "interfacesToPointers", interfacesTo(pointersTo(flatten(
    57  		safeFloat32s,
    58  		safeFloat64s,
    59  	))))
    60  }
    61  
    62  const onlyDouble float64 = 1.0000000000000002
    63  
    64  func TestFloatTruncation(t *testing.T) {
    65  	runTestCases(t, true, "pass", []any{
    66  		truncatingFloat32{save: onlyDouble},
    67  	})
    68  	runTestCases(t, false, "fail", []any{
    69  		truncatingFloat32{save: 1.0},
    70  	})
    71  }
    72  
    73  var safeComplex64s = combine(safeFloat32s, safeFloat32s, func(i, j any) any {
    74  	return complex(i.(float32), j.(float32))
    75  })
    76  
    77  var allComplex64s = combine(allFloat32s, allFloat32s, func(i, j any) any {
    78  	return complex(i.(float32), j.(float32))
    79  })
    80  
    81  var safeComplex128s = combine(safeFloat64s, safeFloat64s, func(i, j any) any {
    82  	return complex(i.(float64), j.(float64))
    83  })
    84  
    85  var allComplex128s = combine(allFloat64s, allFloat64s, func(i, j any) any {
    86  	return complex(i.(float64), j.(float64))
    87  })
    88  
    89  func TestComplex(t *testing.T) {
    90  	runTestCases(t, false, "plain", flatten(
    91  		allComplex64s,
    92  		allComplex128s,
    93  	))
    94  	// See TestFloat; same issue.
    95  	runTestCases(t, false, "pointers", pointersTo(flatten(
    96  		safeComplex64s,
    97  		safeComplex128s,
    98  	)))
    99  	runTestCases(t, false, "interfacse", interfacesTo(flatten(
   100  		safeComplex64s,
   101  		safeComplex128s,
   102  	)))
   103  	runTestCases(t, false, "interfacesTo", interfacesTo(pointersTo(flatten(
   104  		safeComplex64s,
   105  		safeComplex128s,
   106  	))))
   107  }
   108  
   109  func TestComplexTruncation(t *testing.T) {
   110  	runTestCases(t, true, "pass", []any{
   111  		truncatingComplex64{save: complex(onlyDouble, onlyDouble)},
   112  		truncatingComplex64{save: complex(1.0, onlyDouble)},
   113  		truncatingComplex64{save: complex(onlyDouble, 1.0)},
   114  	})
   115  	runTestCases(t, false, "fail", []any{
   116  		truncatingComplex64{save: complex(1.0, 1.0)},
   117  	})
   118  }