go/src/math/bits.go
Mark Pulford a5c44f3e3f math: add RoundToEven function
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>
2017-10-24 22:33:09 +00:00

62 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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
}