mirror of https://github.com/k3s-io/k3s
112 lines
2.6 KiB
Go
112 lines
2.6 KiB
Go
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Copyright ©2015 The Gonum Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package math32
|
|
|
|
import (
|
|
"math"
|
|
)
|
|
|
|
const (
|
|
unan = 0x7fc00000
|
|
uinf = 0x7f800000
|
|
uneginf = 0xff800000
|
|
mask = 0x7f8 >> 3
|
|
shift = 32 - 8 - 1
|
|
bias = 127
|
|
)
|
|
|
|
// Abs returns the absolute value of x.
|
|
//
|
|
// Special cases are:
|
|
// Abs(±Inf) = +Inf
|
|
// Abs(NaN) = NaN
|
|
func Abs(x float32) float32 {
|
|
switch {
|
|
case x < 0:
|
|
return -x
|
|
case x == 0:
|
|
return 0 // return correctly abs(-0)
|
|
}
|
|
return x
|
|
}
|
|
|
|
// Copysign returns a value with the magnitude
|
|
// of x and the sign of y.
|
|
func Copysign(x, y float32) float32 {
|
|
const sign = 1 << 31
|
|
return math.Float32frombits(math.Float32bits(x)&^sign | math.Float32bits(y)&sign)
|
|
}
|
|
|
|
// Hypot returns Sqrt(p*p + q*q), taking care to avoid
|
|
// unnecessary overflow and underflow.
|
|
//
|
|
// Special cases are:
|
|
// Hypot(±Inf, q) = +Inf
|
|
// Hypot(p, ±Inf) = +Inf
|
|
// Hypot(NaN, q) = NaN
|
|
// Hypot(p, NaN) = NaN
|
|
func Hypot(p, q float32) float32 {
|
|
// special cases
|
|
switch {
|
|
case IsInf(p, 0) || IsInf(q, 0):
|
|
return Inf(1)
|
|
case IsNaN(p) || IsNaN(q):
|
|
return NaN()
|
|
}
|
|
if p < 0 {
|
|
p = -p
|
|
}
|
|
if q < 0 {
|
|
q = -q
|
|
}
|
|
if p < q {
|
|
p, q = q, p
|
|
}
|
|
if p == 0 {
|
|
return 0
|
|
}
|
|
q = q / p
|
|
return p * Sqrt(1+q*q)
|
|
}
|
|
|
|
// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
|
|
func Inf(sign int) float32 {
|
|
var v uint32
|
|
if sign >= 0 {
|
|
v = uinf
|
|
} else {
|
|
v = uneginf
|
|
}
|
|
return math.Float32frombits(v)
|
|
}
|
|
|
|
// IsInf reports whether f is an infinity, according to sign.
|
|
// If sign > 0, IsInf reports whether f is positive infinity.
|
|
// If sign < 0, IsInf reports whether f is negative infinity.
|
|
// If sign == 0, IsInf reports whether f is either infinity.
|
|
func IsInf(f float32, sign int) bool {
|
|
// Test for infinity by comparing against maximum float.
|
|
// To avoid the floating-point hardware, could use:
|
|
// x := math.Float32bits(f);
|
|
// return sign >= 0 && x == uinf || sign <= 0 && x == uneginf;
|
|
return sign >= 0 && f > math.MaxFloat32 || sign <= 0 && f < -math.MaxFloat32
|
|
}
|
|
|
|
// IsNaN reports whether f is an IEEE 754 ``not-a-number'' value.
|
|
func IsNaN(f float32) (is bool) {
|
|
// IEEE 754 says that only NaNs satisfy f != f.
|
|
// To avoid the floating-point hardware, could use:
|
|
// x := math.Float32bits(f);
|
|
// return uint32(x>>shift)&mask == mask && x != uinf && x != uneginf
|
|
return f != f
|
|
}
|
|
|
|
// NaN returns an IEEE 754 ``not-a-number'' value.
|
|
func NaN() float32 { return math.Float32frombits(unan) }
|