Skip to content

Commit 2a58211

Browse files
committed
fix Float64 docs, fix bug in SetFloat64
Fixes: #88 Fixes: #89
1 parent 9de02cb commit 2a58211

File tree

1 file changed

+20
-22
lines changed

1 file changed

+20
-22
lines changed

big.go

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -480,11 +480,11 @@ func (z *Big) CopySign(x, y *Big) *Big {
480480
return z
481481
}
482482

483-
// Float64 returns x as a float64 and a bool indicating whether x can be exactly
484-
// represented as a float64. Special values are considered exact; however, special
485-
// values that occur because the magnitude of x is too large to be represented
486-
// as a float64 are not.
487-
func (x *Big) Float64() (f float64, exact bool) {
483+
// Float64 returns x as a float64 and a bool indicating whether x can fit into
484+
// a float64 without truncation, overflow, or underflow. Special values are
485+
// considered exact; however, special values that occur because the magnitude of
486+
// x is too large to be represented as a float64 are not.
487+
func (x *Big) Float64() (f float64, ok bool) {
488488
if debug {
489489
x.validate()
490490
}
@@ -505,23 +505,22 @@ func (x *Big) Float64() (f float64, exact bool) {
505505
switch {
506506
case !x.isCompact():
507507
f, _ = strconv.ParseFloat(x.String(), 64)
508-
exact = false
509-
//f, exact = math.Inf(0), false
508+
ok = !math.IsInf(f, 0) && !math.IsNaN(f)
510509
case x.compact == 0:
511-
exact = true
510+
ok = true
512511
case x.exp == 0:
513-
f, exact = float64(x.compact), true
512+
f, ok = float64(x.compact), true
514513
case x.exp > 0:
515514
f = float64(x.compact) * math.Pow10(x.exp)
516-
exact = x.compact < maxMantissa && x.exp < maxPow10
515+
ok = x.compact < maxMantissa && x.exp < maxPow10
517516
case x.exp < 0:
518517
f = float64(x.compact) / math.Pow10(-x.exp)
519-
exact = x.compact < maxMantissa && x.exp > -maxPow10
518+
ok = x.compact < maxMantissa && x.exp > -maxPow10
520519
}
521520
if x.form&signbit != 0 {
522521
f = math.Copysign(f, -1)
523522
}
524-
return f, exact
523+
return f, ok
525524
}
526525

527526
// Float sets z to x and returns z. z is allowed to be nil. The result is
@@ -1191,7 +1190,7 @@ func (z *Big) SetFloat64(x float64) *Big {
11911190
}
11921191

11931192
shift := 52 - exp
1194-
for mantissa&1 == 0 {
1193+
for mantissa&1 == 0 && shift > 0 {
11951194
mantissa >>= 1
11961195
shift--
11971196
}
@@ -1204,19 +1203,18 @@ func (z *Big) SetFloat64(x float64) *Big {
12041203
z.unscaled.Exp(c.FiveInt, &z.unscaled, nil)
12051204
arith.MulUint64(&z.unscaled, &z.unscaled, mantissa)
12061205
z.exp = -shift
1207-
return z.norm()
1208-
}
1209-
1210-
if s := uint(-shift); s < 64 {
1211-
z.compact = mantissa << s
1212-
z.precision = arith.Length(z.compact)
12131206
} else {
1207+
// TODO(eric): figure out why this doesn't work for _some_ numbers. See
1208+
// https://github.com/ericlagergren/decimal/issues/89
1209+
//
1210+
// z.compact = mantissa << uint(-shift)
1211+
// z.precision = arith.Length(z.compact)
1212+
12141213
z.compact = c.Inflated
12151214
z.unscaled.SetUint64(mantissa)
1216-
z.unscaled.Lsh(&z.unscaled, s)
1217-
z.norm()
1215+
z.unscaled.Lsh(&z.unscaled, uint(-shift))
12181216
}
1219-
return z
1217+
return z.norm()
12201218
}
12211219

12221220
// SetInf sets z to -Inf if signbit is set or +Inf is signbit is not set, and

0 commit comments

Comments
 (0)