OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / internal / math32 / math.go
1 // Copyright 2009 The Go 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.
4
5 // Copyright ©2015 The Gonum Authors. All rights reserved.
6 // Use of this source code is governed by a BSD-style
7 // license that can be found in the LICENSE file.
8
9 package math32
10
11 import (
12         "math"
13 )
14
15 const (
16         unan    = 0x7fc00000
17         uinf    = 0x7f800000
18         uneginf = 0xff800000
19         mask    = 0x7f8 >> 3
20         shift   = 32 - 8 - 1
21         bias    = 127
22 )
23
24 // Abs returns the absolute value of x.
25 //
26 // Special cases are:
27 //      Abs(±Inf) = +Inf
28 //      Abs(NaN) = NaN
29 func Abs(x float32) float32 {
30         switch {
31         case x < 0:
32                 return -x
33         case x == 0:
34                 return 0 // return correctly abs(-0)
35         }
36         return x
37 }
38
39 // Copysign returns a value with the magnitude
40 // of x and the sign of y.
41 func Copysign(x, y float32) float32 {
42         const sign = 1 << 31
43         return math.Float32frombits(math.Float32bits(x)&^sign | math.Float32bits(y)&sign)
44 }
45
46 // Hypot returns Sqrt(p*p + q*q), taking care to avoid
47 // unnecessary overflow and underflow.
48 //
49 // Special cases are:
50 //      Hypot(±Inf, q) = +Inf
51 //      Hypot(p, ±Inf) = +Inf
52 //      Hypot(NaN, q) = NaN
53 //      Hypot(p, NaN) = NaN
54 func Hypot(p, q float32) float32 {
55         // special cases
56         switch {
57         case IsInf(p, 0) || IsInf(q, 0):
58                 return Inf(1)
59         case IsNaN(p) || IsNaN(q):
60                 return NaN()
61         }
62         if p < 0 {
63                 p = -p
64         }
65         if q < 0 {
66                 q = -q
67         }
68         if p < q {
69                 p, q = q, p
70         }
71         if p == 0 {
72                 return 0
73         }
74         q = q / p
75         return p * Sqrt(1+q*q)
76 }
77
78 // Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
79 func Inf(sign int) float32 {
80         var v uint32
81         if sign >= 0 {
82                 v = uinf
83         } else {
84                 v = uneginf
85         }
86         return math.Float32frombits(v)
87 }
88
89 // IsInf reports whether f is an infinity, according to sign.
90 // If sign > 0, IsInf reports whether f is positive infinity.
91 // If sign < 0, IsInf reports whether f is negative infinity.
92 // If sign == 0, IsInf reports whether f is either infinity.
93 func IsInf(f float32, sign int) bool {
94         // Test for infinity by comparing against maximum float.
95         // To avoid the floating-point hardware, could use:
96         //      x := math.Float32bits(f);
97         //      return sign >= 0 && x == uinf || sign <= 0 && x == uneginf;
98         return sign >= 0 && f > math.MaxFloat32 || sign <= 0 && f < -math.MaxFloat32
99 }
100
101 // IsNaN reports whether f is an IEEE 754 ``not-a-number'' value.
102 func IsNaN(f float32) (is bool) {
103         // IEEE 754 says that only NaNs satisfy f != f.
104         // To avoid the floating-point hardware, could use:
105         //      x := math.Float32bits(f);
106         //      return uint32(x>>shift)&mask == mask && x != uinf && x != uneginf
107         return f != f
108 }
109
110 // NaN returns an IEEE 754 ``not-a-number'' value.
111 func NaN() float32 { return math.Float32frombits(unan) }