}
// Convert mantissa into decimal representation.
- s := m.itoa(10)
+ s := m.utoa(10)
n := len(s)
x.exp = n
// Trim trailing zeros; instead the exponent is tracking
// Approach: All numbers in the interval [x - 1/2ulp, x + 1/2ulp]
// (possibly exclusive) round to x for the given precision of x.
// Compute the lower and upper bound in decimal form and find the
- // the shortest decimal number d such that lower <= d <= upper.
+ // shortest decimal number d such that lower <= d <= upper.
// TODO(gri) strconv/ftoa.do describes a shortcut in some cases.
// See if we can use it (in adjusted form) here as well.
m = nat(nil).shr(m, uint(w-x.prec))
}
- buf = append(buf, m.itoa(10)...)
+ buf = append(buf, m.utoa(10)...)
buf = append(buf, 'p')
e := int64(x.exp) - int64(x.prec)
if e >= 0 {
m = m[i:]
buf = append(buf, "0x."...)
- buf = append(buf, bytes.TrimRight(m.itoa(16), "0")...)
+ buf = append(buf, bytes.TrimRight(m.utoa(16), "0")...)
buf = append(buf, 'p')
if x.exp >= 0 {
buf = append(buf, '+')
if x == nil {
return "<nil>"
}
- s := string(x.abs.itoa(base))
- if x.neg {
- s = "-" + s
- }
- return s
+ return string(x.abs.itoa(x.neg, base))
}
// Append appends the string representation of x, as generated by
if x == nil {
return append(buf, "<nil>"...)
}
- if x.neg {
- buf = append(buf, '-')
- }
- return append(buf, x.abs.itoa(base)...)
+ return append(buf, x.abs.itoa(x.neg, base)...)
}
func (x *Int) String() string {
}
}
- digits := x.abs.itoa(base)
+ digits := x.abs.utoa(base)
if ch == 'X' {
// faster than bytes.ToUpper
for i, d := range digits {
func TestMulRangeN(t *testing.T) {
for i, r := range mulRangesN {
- prod := string(nat(nil).mulRange(r.a, r.b).itoa(10))
+ prod := string(nat(nil).mulRange(r.a, r.b).utoa(10))
if prod != r.prod {
t.Errorf("#%d: got %s; want %s", i, prod, r.prod)
}
for i := uint(0); i <= 3*_W; i++ {
n := y.trailingZeroBits()
if n != i {
- t.Errorf("got 0x%s.trailingZeroBits() = %d; want %d", y.itoa(16), n, i)
+ t.Errorf("got 0x%s.trailingZeroBits() = %d; want %d", y.utoa(16), n, i)
}
y = y.shl(y, 1)
}
z := nat(nil).montgomery(x, y, m, k0, len(m))
z = z.norm()
if z.cmp(out) != 0 {
- t.Errorf("#%d got %s want %s", i, z.itoa(10), out.itoa(10))
+ t.Errorf("#%d got %s want %s", i, z.utoa(10), out.utoa(10))
}
}
}
z := nat(nil).expNN(x, y, m)
if z.cmp(out) != 0 {
- t.Errorf("#%d got %s want %s", i, z.itoa(10), out.itoa(10))
+ t.Errorf("#%d got %s want %s", i, z.utoa(10), out.utoa(10))
}
}
}
func TestFibo(t *testing.T) {
for i, want := range fiboNums {
n := i * 10
- got := string(fibo(n).itoa(10))
+ got := string(fibo(n).utoa(10))
if got != want {
t.Errorf("fibo(%d) failed: got %s want %s", n, got, want)
}
return
}
-// itoa converts x to an ASCII representation in the given base;
+// utoa converts x to an ASCII representation in the given base;
// base must be between 2 and MaxBase, inclusive.
-func (x nat) itoa(base int) []byte {
+func (x nat) utoa(base int) []byte {
+ return x.itoa(false, base)
+}
+
+// itoa is like utoa but it prepends a '-' if neg && x != 0.
+func (x nat) itoa(neg bool, base int) []byte {
if base < 2 || base > MaxBase {
panic("invalid base")
}
// allocate buffer for conversion
i := int(float64(x.bitLen())/math.Log2(float64(base))) + 1 // off by 1 at most
+ if neg {
+ i++
+ }
s := make([]byte, i)
// convert power of two and non power of two bases separately
}
}
+ if neg {
+ i--
+ s[i] = '-'
+ }
+
return s[i:]
}
defer func() {
panicStr = recover().(string)
}()
- natOne.itoa(1)
+ natOne.utoa(1)
}()
if panicStr != "invalid base" {
t.Errorf("expected panic for invalid base")
}
for _, a := range strTests {
- s := string(a.x.itoa(a.b))
+ s := string(a.x.utoa(a.b))
if s != a.s {
t.Errorf("string%+v\n\tgot s = %s; want %s", a, s, a.s)
}
if err != nil {
t.Errorf("scanning pi: %s", err)
}
- if s := string(z.itoa(10)); s != pi {
+ if s := string(z.utoa(10)); s != pi {
t.Errorf("scanning pi: got %s", s)
}
}
func BenchmarkStringPiParallel(b *testing.B) {
var x nat
x, _, _, _ = x.scan(strings.NewReader(pi), 0, false)
- if string(x.itoa(10)) != pi {
+ if string(x.utoa(10)) != pi {
panic("benchmark incorrect: conversion failed")
}
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
- x.itoa(10)
+ x.utoa(10)
}
})
}
var z nat
z = z.expWW(x, y)
- s := z.itoa(base)
+ s := z.utoa(base)
if t := itoa(z, base); !bytes.Equal(s, t) {
b.Fatalf("scanning: got %s; want %s", s, t)
}
b.StopTimer()
var z nat
z = z.expWW(x, y)
- z.itoa(base) // warm divisor cache
+ z.utoa(base) // warm divisor cache
b.StartTimer()
for i := 0; i < b.N; i++ {
- _ = z.itoa(base)
+ _ = z.utoa(base)
}
}
b.StopTimer()
var z nat
z = z.expWW(Word(base), Word(d)) // build target number
- _ = z.itoa(base) // warm divisor cache
+ _ = z.utoa(base) // warm divisor cache
b.StartTimer()
for i := 0; i < b.N; i++ {
- _ = z.itoa(base)
+ _ = z.utoa(base)
}
}
for b := 2; b <= 16; b++ {
for p = 0; p <= 512; p++ {
x := nat(nil).expWW(Word(b), p)
- xs := x.itoa(b)
+ xs := x.utoa(b)
xs2 := itoa(x, b)
if !bytes.Equal(xs, xs2) {
t.Errorf("failed at %d ** %d in base %d: %s != %s", b, p, b, xs, xs2)
// String returns a string representation of x in the form "a/b" (even if b == 1).
func (x *Rat) String() string {
- s := "/1"
+ var buf []byte
+ buf = x.a.Append(buf, 10)
+ buf = append(buf, '/')
if len(x.b.abs) != 0 {
- s = "/" + string(x.b.abs.itoa(10))
+ buf = x.b.Append(buf, 10)
+ } else {
+ buf = append(buf, '1')
}
- return x.a.String() + s
+ return string(buf)
}
// RatString returns a string representation of x in the form "a/b" if b != 1,
// digits of precision after the decimal point. The last digit is rounded to
// nearest, with halves rounded away from zero.
func (x *Rat) FloatString(prec int) string {
+ var buf []byte
+
if x.IsInt() {
- s := x.a.String()
+ buf = x.a.Append(buf, 10)
if prec > 0 {
- s += "." + strings.Repeat("0", prec)
+ buf = append(buf, '.')
+ for i := prec; i > 0; i-- {
+ buf = append(buf, '0')
+ }
}
- return s
+ return string(buf)
}
// x.b.abs != 0
}
}
- s := string(q.itoa(10))
if x.a.neg {
- s = "-" + s
+ buf = append(buf, '-')
}
+ buf = append(buf, q.utoa(10)...) // itoa ignores sign if q == 0
if prec > 0 {
- rs := string(r.itoa(10))
- leadingZeros := prec - len(rs)
- s += "." + strings.Repeat("0", leadingZeros) + rs
+ buf = append(buf, '.')
+ rs := r.utoa(10)
+ for i := prec - len(rs); i > 0; i-- {
+ buf = append(buf, '0')
+ }
+ buf = append(buf, rs...)
}
- return s
+ return string(buf)
}