mirror of
https://github.com/golang/go.git
synced 2026-04-21 03:10:31 +00:00
Rounding ties to even is statistically useful for some applications. This implementation completes IEEE float64 rounding mode support (in addition to Round, Ceil, Floor, Trunc). This function avoids subtle faults found in ad-hoc implementations, and is simple enough to be inlined by the compiler. Fixes #21748 Change-Id: I09415df2e42435f9e7dabe3bdc0148e9b9ebd609 Reviewed-on: https://go-review.googlesource.com/61211 Reviewed-by: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
62 lines
1.9 KiB
Go
62 lines
1.9 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.
|
||
|
||
package math
|
||
|
||
const (
|
||
uvnan = 0x7FF8000000000001
|
||
uvinf = 0x7FF0000000000000
|
||
uvneginf = 0xFFF0000000000000
|
||
uvone = 0x3FF0000000000000
|
||
mask = 0x7FF
|
||
shift = 64 - 11 - 1
|
||
bias = 1023
|
||
signMask = 1 << 63
|
||
fracMask = 1<<shift - 1
|
||
)
|
||
|
||
// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
|
||
func Inf(sign int) float64 {
|
||
var v uint64
|
||
if sign >= 0 {
|
||
v = uvinf
|
||
} else {
|
||
v = uvneginf
|
||
}
|
||
return Float64frombits(v)
|
||
}
|
||
|
||
// NaN returns an IEEE 754 ``not-a-number'' value.
|
||
func NaN() float64 { return Float64frombits(uvnan) }
|
||
|
||
// IsNaN reports whether f is an IEEE 754 ``not-a-number'' value.
|
||
func IsNaN(f float64) (is bool) {
|
||
// IEEE 754 says that only NaNs satisfy f != f.
|
||
// To avoid the floating-point hardware, could use:
|
||
// x := Float64bits(f);
|
||
// return uint32(x>>shift)&mask == mask && x != uvinf && x != uvneginf
|
||
return f != f
|
||
}
|
||
|
||
// 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 float64, sign int) bool {
|
||
// Test for infinity by comparing against maximum float.
|
||
// To avoid the floating-point hardware, could use:
|
||
// x := Float64bits(f);
|
||
// return sign >= 0 && x == uvinf || sign <= 0 && x == uvneginf;
|
||
return sign >= 0 && f > MaxFloat64 || sign <= 0 && f < -MaxFloat64
|
||
}
|
||
|
||
// normalize returns a normal number y and exponent exp
|
||
// satisfying x == y × 2**exp. It assumes x is finite and non-zero.
|
||
func normalize(x float64) (y float64, exp int) {
|
||
const SmallestNormal = 2.2250738585072014e-308 // 2**-1022
|
||
if Abs(x) < SmallestNormal {
|
||
return x * (1 << 52), -52
|
||
}
|
||
return x, 0
|
||
}
|