Commit 15594df6 authored by Robert Griesemer's avatar Robert Griesemer

math/big: handling of +/-Inf and zero precision, enable zero values

- clarified representation of +/-Inf
- only 0 and Inf values can have 0 precision
- a zero precision value used as result value takes the max precision
  of the arguments (to be fine-tuned for setters)
- the zero precision approach makes Float zero values possible
  (they represent +0)
- more tests

Missing: Filling in the blanks. More tests.

Change-Id: Ibb4f97e12e1f356c3085ce80f3464e97b82ac130
Reviewed-on: https://go-review.googlesource.com/4000Reviewed-by: 's avatarAlan Donovan <adonovan@google.com>
parent 9b6ccb13
This diff is collapsed.
......@@ -6,11 +6,70 @@ package big
import (
"fmt"
"math"
"sort"
"strconv"
"testing"
)
func TestFloatZeroValue(t *testing.T) {
// zero (uninitialized) value is a ready-to-use 0.0
var x Float
if s := x.Format('f', 1); s != "0.0" {
t.Errorf("zero value = %s; want 0.0", s)
}
// zero value has precision 0
if prec := x.Precision(); prec != 0 {
t.Errorf("prec = %d; want 0", prec)
}
// zero value can be used in any and all positions of binary operations
make := func(x int) *Float {
if x == 0 {
return new(Float) // 0 translates into the zero value
}
return NewFloat(float64(x), 10, 0)
}
for _, test := range []struct {
z, x, y, want int
opname rune
op func(z, x, y *Float) *Float
}{
{0, 0, 0, 0, '+', (*Float).Add},
{0, 1, 2, 3, '+', (*Float).Add},
{1, 2, 0, 2, '+', (*Float).Add},
{2, 0, 1, 1, '+', (*Float).Add},
{0, 0, 0, 0, '-', (*Float).Sub},
{0, 1, 2, -1, '-', (*Float).Sub},
{1, 2, 0, 2, '-', (*Float).Sub},
{2, 0, 1, -1, '-', (*Float).Sub},
{0, 0, 0, 0, '*', (*Float).Mul},
{0, 1, 2, 2, '*', (*Float).Mul},
{1, 2, 0, 0, '*', (*Float).Mul},
{2, 0, 1, 0, '*', (*Float).Mul},
{0, 0, 0, 0, '/', (*Float).Quo},
{0, 2, 1, 2, '/', (*Float).Quo},
{1, 2, 0, 0, '/', (*Float).Quo},
{2, 0, 1, 0, '/', (*Float).Quo},
} {
z := make(test.z)
test.op(z, make(test.x), make(test.y))
if got := int(z.Int64()); got != test.want {
t.Errorf("%d %c %d = %d; want %d", test.x, test.opname, test.y, got, test.want)
}
}
// TODO(gri) test how precision is set for zero value results
}
func TestFloatInf(t *testing.T) {
// TODO(gri) implement this
}
func fromBinary(s string) int64 {
x, err := strconv.ParseInt(s, 2, 64)
if err != nil {
......@@ -244,6 +303,9 @@ func TestFloatSetFloat64(t *testing.T) {
3.14159265e10,
2.718281828e-123,
1.0 / 3,
math.Inf(-1),
math.Inf(0),
-math.Inf(1),
} {
for i := range [2]int{} {
if i&1 != 0 {
......
......@@ -191,13 +191,26 @@ func (x *Float) Format(format byte, prec int) string {
// Append appends the string form of the floating-point number x,
// as generated by x.Format, to buf and returns the extended buffer.
func (x *Float) Append(buf []byte, format byte, prec int) []byte {
// pick off simple cases
// TODO(gri) factor out handling of sign?
// Inf
if x.IsInf(0) {
var ch byte = '+'
if x.neg {
ch = '-'
}
buf = append(buf, ch)
return append(buf, "Inf"...)
}
// easy formats
switch format {
case 'b':
return x.bstring(buf)
case 'p':
return x.pstring(buf)
}
return x.bigFtoa(buf, format, prec)
}
......@@ -212,7 +225,6 @@ func (x *Float) String() string {
// The mantissa is normalized such that is uses x.Precision() bits in binary
// representation.
func (x *Float) bstring(buf []byte) []byte {
// TODO(gri) handle Inf
if x.neg {
buf = append(buf, '-')
}
......@@ -240,7 +252,6 @@ func (x *Float) bstring(buf []byte) []byte {
// ad returns the extended buffer.
// The mantissa is normalized such that 0.5 <= 0.mantissa < 1.0.
func (x *Float) pstring(buf []byte) []byte {
// TODO(gri) handle Inf
if x.neg {
buf = append(buf, '-')
}
......
......@@ -192,9 +192,9 @@ func TestFloat64Format(t *testing.T) {
// {math.NaN(), 'g', -1, "NaN"},
// {-math.NaN(), 'g', -1, "NaN"},
// {math.Inf(0), 'g', -1, "+Inf"},
// {math.Inf(-1), 'g', -1, "-Inf"},
// {-math.Inf(0), 'g', -1, "-Inf"},
{math.Inf(0), 'g', -1, "+Inf"},
{math.Inf(-1), 'g', -1, "-Inf"},
{-math.Inf(0), 'g', -1, "-Inf"},
{-1, 'b', -1, "-4503599627370496p-52"},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment