1 // Copyright ©2015 The Gonum Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 "gonum.org/v1/gonum/floats"
17 func TestAbs(t *testing.T) {
18 f := func(x float32) bool {
20 return y == float32(math.Abs(float64(x)))
22 if err := quick.Check(f, nil); err != nil {
27 func TestCopySign(t *testing.T) {
28 f := func(x struct{ X, Y float32 }) bool {
29 y := Copysign(x.X, x.Y)
30 return y == float32(math.Copysign(float64(x.X), float64(x.Y)))
32 if err := quick.Check(f, nil); err != nil {
37 func TestHypot(t *testing.T) {
38 // tol is increased for Hypot to avoid failures
39 // related to https://github.com/gonum/gonum/issues/110.
41 f := func(x struct{ X, Y float32 }) bool {
43 if math.Hypot(float64(x.X), float64(x.Y)) > math.MaxFloat32 {
46 return floats.EqualWithinRel(float64(y), math.Hypot(float64(x.X), float64(x.Y)), tol)
48 if err := quick.Check(f, nil); err != nil {
53 func TestInf(t *testing.T) {
54 if float64(Inf(1)) != math.Inf(1) || float64(Inf(-1)) != math.Inf(-1) {
55 t.Error("float32(inf) not infinite")
59 func TestIsInf(t *testing.T) {
60 posInf := float32(math.Inf(1))
61 negInf := float32(math.Inf(-1))
62 if !IsInf(posInf, 0) || !IsInf(negInf, 0) || !IsInf(posInf, 1) || !IsInf(negInf, -1) || IsInf(posInf, -1) || IsInf(negInf, 1) {
63 t.Error("unexpected isInf value")
69 y := IsInf(x.F, x.Sign)
70 return y == math.IsInf(float64(x.F), x.Sign)
72 if err := quick.Check(f, nil); err != nil {
77 func TestIsNaN(t *testing.T) {
78 f := func(x float32) bool {
80 return y == math.IsNaN(float64(x))
82 if err := quick.Check(f, nil); err != nil {
87 func TestNaN(t *testing.T) {
88 if !math.IsNaN(float64(NaN())) {
89 t.Errorf("float32(nan) is a number: %f", NaN())
93 func TestSignbit(t *testing.T) {
94 f := func(x float32) bool {
95 return Signbit(x) == math.Signbit(float64(x))
97 if err := quick.Check(f, nil); err != nil {
102 func TestSqrt(t *testing.T) {
103 f := func(x float32) bool {
105 if IsNaN(y) && IsNaN(sqrt(x)) {
108 return floats.EqualWithinRel(float64(y), float64(sqrt(x)), tol)
110 if err := quick.Check(f, nil); err != nil {
115 // Copyright 2009 The Go Authors. All rights reserved.
116 // Use of this source code is governed by a BSD-style
117 // license that can be found in the LICENSE file.
119 // The original C code and the long comment below are
120 // from FreeBSD's /usr/src/lib/msun/src/e_sqrt.c and
121 // came with this notice. The go code is a simplified
122 // version of the original C.
124 // ====================================================
125 // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
127 // Developed at SunPro, a Sun Microsystems, Inc. business.
128 // Permission to use, copy, modify, and distribute this
129 // software is freely granted, provided that this notice
131 // ====================================================
134 // Return correctly rounded sqrt.
135 // -----------------------------------------
136 // | Use the hardware sqrt if you have one |
137 // -----------------------------------------
139 // Bit by bit method using integer arithmetic. (Slow, but portable)
141 // Scale x to y in [1,4) with even powers of 2:
142 // find an integer k such that 1 <= (y=x*2**(2k)) < 4, then
143 // sqrt(x) = 2**k * sqrt(y)
144 // 2. Bit by bit computation
145 // Let q = sqrt(y) truncated to i bit after binary point (q = 1),
148 // s = 2*q , and y = 2 * ( y - q ). (1)
151 // To compute q from q , one checks whether
155 // (q + 2 ) <= y. (2)
158 // If (2) is false, then q = q ; otherwise q = q + 2 .
161 // With some algebraic manipulation, it is not difficult to see
162 // that (2) is equivalent to
167 // The advantage of (3) is that s and y can be computed by
169 // the following recurrence formula:
172 // s = s , y = y ; (4)
177 // s = s + 2 , y = y - s - 2 (5)
180 // One may easily use induction to prove (4) and (5).
181 // Note. Since the left hand side of (3) contain only i+2 bits,
182 // it does not necessary to do a full (53-bit) comparison
185 // After generating the 53 bits result, we compute one more bit.
186 // Together with the remainder, we can decide whether the
187 // result is exact, bigger than 1/2ulp, or less than 1/2ulp
188 // (it will never equal to 1/2ulp).
189 // The rounding mode can be detected by checking whether
190 // huge + tiny is equal to huge, and whether huge - tiny is
191 // equal to huge for some floating point number "huge" and "tiny".
193 func sqrt(x float32) float32 {
196 case x == 0 || IsNaN(x) || IsInf(x, 1):
201 ix := math.Float32bits(x)
203 exp := int((ix >> shift) & mask)
204 if exp == 0 { // subnormal x
205 for ix&1<<shift == 0 {
211 exp -= bias // unbias exponent
214 if exp&1 == 1 { // odd exp, double x to make it even
217 exp >>= 1 // exp = exp/2, exponent of square root
218 // generate sqrt(x) bit by bit
220 var q, s uint32 // q = sqrt(x)
221 r := uint32(1 << (shift + 1)) // r = moving bit from MSB to LSB
233 if ix != 0 { // remainder, result not exact
234 q += q & 1 // round according to extra bit
236 ix = q>>1 + uint32(exp-1+bias)<<shift // significand + biased exponent
237 return math.Float32frombits(ix)