blob: d85ee9cb137775ad39aaafc9c2e72b851449abdd [file] [log] [blame]
Russ Cox488ca3c2009-10-15 23:09:22 -07001// 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
5package math
6
7const (
Shenghou Ma6e9506a2012-08-07 09:57:14 +08008 uvnan = 0x7FF8000000000001
Robert Griesemera3d10452009-12-15 15:35:38 -08009 uvinf = 0x7FF0000000000000
10 uvneginf = 0xFFF0000000000000
11 mask = 0x7FF
12 shift = 64 - 11 - 1
Eoghan Sherry976e4572010-12-15 13:20:52 -050013 bias = 1023
Russ Cox488ca3c2009-10-15 23:09:22 -070014)
15
16// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
17func Inf(sign int) float64 {
Robert Griesemera3d10452009-12-15 15:35:38 -080018 var v uint64
Russ Cox488ca3c2009-10-15 23:09:22 -070019 if sign >= 0 {
Robert Griesemer40621d52009-11-09 12:07:39 -080020 v = uvinf
Russ Cox488ca3c2009-10-15 23:09:22 -070021 } else {
Robert Griesemer40621d52009-11-09 12:07:39 -080022 v = uvneginf
Russ Cox488ca3c2009-10-15 23:09:22 -070023 }
Robert Griesemera3d10452009-12-15 15:35:38 -080024 return Float64frombits(v)
Russ Cox488ca3c2009-10-15 23:09:22 -070025}
26
27// NaN returns an IEEE 754 ``not-a-number'' value.
Robert Griesemera3d10452009-12-15 15:35:38 -080028func NaN() float64 { return Float64frombits(uvnan) }
Russ Cox488ca3c2009-10-15 23:09:22 -070029
Rob Pikeabe384f2013-07-23 11:59:49 +100030// IsNaN reports whether f is an IEEE 754 ``not-a-number'' value.
Russ Cox488ca3c2009-10-15 23:09:22 -070031func IsNaN(f float64) (is bool) {
Russ Cox1e9e7ec2009-12-15 17:21:01 -080032 // IEEE 754 says that only NaNs satisfy f != f.
33 // To avoid the floating-point hardware, could use:
34 // x := Float64bits(f);
35 // return uint32(x>>shift)&mask == mask && x != uvinf && x != uvneginf
36 return f != f
Russ Cox488ca3c2009-10-15 23:09:22 -070037}
38
Rob Pikeabe384f2013-07-23 11:59:49 +100039// IsInf reports whether f is an infinity, according to sign.
40// If sign > 0, IsInf reports whether f is positive infinity.
41// If sign < 0, IsInf reports whether f is negative infinity.
42// If sign == 0, IsInf reports whether f is either infinity.
Russ Cox488ca3c2009-10-15 23:09:22 -070043func IsInf(f float64, sign int) bool {
Russ Cox1e9e7ec2009-12-15 17:21:01 -080044 // Test for infinity by comparing against maximum float.
45 // To avoid the floating-point hardware, could use:
46 // x := Float64bits(f);
47 // return sign >= 0 && x == uvinf || sign <= 0 && x == uvneginf;
48 return sign >= 0 && f > MaxFloat64 || sign <= 0 && f < -MaxFloat64
Russ Cox488ca3c2009-10-15 23:09:22 -070049}
Eoghan Sherry13c2e622011-01-19 14:23:59 -050050
51// normalize returns a normal number y and exponent exp
52// satisfying x == y × 2**exp. It assumes x is finite and non-zero.
53func normalize(x float64) (y float64, exp int) {
54 const SmallestNormal = 2.2250738585072014e-308 // 2**-1022
Rob Pike1a13f9b2011-09-29 09:54:20 -070055 if Abs(x) < SmallestNormal {
Eoghan Sherry13c2e622011-01-19 14:23:59 -050056 return x * (1 << 52), -52
57 }
58 return x, 0
59}