Skip to content
This repository has been archived by the owner on Sep 1, 2021. It is now read-only.

Commit

Permalink
Add a two-digit table
Browse files Browse the repository at this point in the history
This is a small improvement for some inputs:

name                                     old time/op  new time/op  delta
AppendFloat64/0e+00-12                   3.35ns ± 2%  3.30ns ± 2%     ~     (p=0.111 n=5+5)
AppendFloat64/1e+00-12                   15.3ns ± 1%  15.3ns ± 1%     ~     (p=0.778 n=5+5)
AppendFloat64/3e-01-12                   51.0ns ± 1%  50.0ns ± 1%   -1.96%  (p=0.016 n=5+5)
AppendFloat64/1e+06-12                   20.8ns ± 2%  20.8ns ± 1%     ~     (p=0.810 n=5+5)
AppendFloat64/-1.2345e+02-12             51.6ns ± 2%  49.5ns ± 1%   -4.15%  (p=0.008 n=5+5)
AppendFloat64/6.226662346353213e-309-12  44.5ns ± 1%  39.1ns ± 1%  -12.14%  (p=0.008 n=5+5)
  • Loading branch information
cespare committed Jan 13, 2019
1 parent bf6487c commit 463ddad
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 5 deletions.
9 changes: 9 additions & 0 deletions maketables.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ const (
func main() {
b := bytes.NewBuffer(header)

fmt.Fprintln(b, "var twoDigits = [200]byte{")
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
fmt.Fprintf(b, "'%c','%c',", '0'+i, '0'+j)
}
fmt.Fprintln(b)
}
fmt.Fprintln(b, "\n}")

fmt.Fprintf(b, "const pow5NumBits32 = %d\n", pow5NumBits32)
fmt.Fprintln(b, "var pow5Split32 = [...]uint64{")
for i := int64(0); i < posTableSize32; i++ {
Expand Down
5 changes: 5 additions & 0 deletions ryu.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ func pow5Bits(e int32) int32 {
return int32((uint32(e)*1217359)>>19 + 1)
}

func copyTwoDigits(b []byte, d uint) {
b[0] = twoDigits[d]
b[1] = twoDigits[d+1]
}

// FIXME(caleb): Document how these are optimized.

func boolToUint32(b bool) uint32 {
Expand Down
57 changes: 52 additions & 5 deletions ryu64.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,66 @@ func (d dec64) append(b []byte, neg bool) []byte {
}

// Print the decimal digits.
// FIXME: optimize.
n := len(b)
if cap(b)-len(b) >= bufLen {
// Avoid function call in the common case.
b = b[:len(b)+bufLen]
} else {
b = append(b, make([]byte, bufLen)...)
}
for i := 0; i < outLen-1; i++ {
b[n+outLen-i] = '0' + byte(out%10)
out /= 10
// The code below is equivalent to the following:
// for i := 0; i < outLen-1; i++ {
// b[n+outLen-i] = '0' + byte(out%10)
// out /= 10
// }
// b[n] = '0' + byte(out%10)

// We prefer 32-bit divisions even on 64-bit platforms.
// We have at most 17 digits, and uint32 can store 9 digits.
// If the output doesn't fit into a uint32, cut off 8 digits
// so the rest will fit into a uint32.
var i int
if out>>32 > 0 {
// FIXME: bits.Div?
q, r := out/1e8, out%1e8
out = q

c := r % 1e4
r /= 1e4
d := r % 1e4
c0 := uint(c%100) << 1
c1 := uint(c/100) << 1
d0 := uint(d%100) << 1
d1 := uint(d/100) << 1
copyTwoDigits(b[n+outLen-i-7:], d1)
copyTwoDigits(b[n+outLen-i-5:], d0)
copyTwoDigits(b[n+outLen-i-3:], c1)
copyTwoDigits(b[n+outLen-i-1:], c0)
i += 8
}
out32 := uint32(out)
for ; out32 >= 1e4; i += 4 {
c := out32 % 1e4
out32 /= 1e4
c0 := uint(c%100) << 1
c1 := uint(c/100) << 1
copyTwoDigits(b[n+outLen-i-1:], c0)
copyTwoDigits(b[n+outLen-i-3:], c1)
}
if out32 >= 100 {
c := uint(out32%100) << 1
out32 /= 100
copyTwoDigits(b[n+outLen-i-1:], c)
i += 2
}
if out32 >= 10 {
c := out32 << 1
// The dot goes between the digits.
b[n+outLen-i] = twoDigits[c+1]
b[n] = twoDigits[c]
} else {
b[n] = '0' + byte(out32)
}
b[n] = '0' + byte(out%10)

// Print the '.' if needed.
if outLen > 1 {
Expand Down
4 changes: 4 additions & 0 deletions ryu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ var float64TestCases = []float64{
2.2250738585072012e-308,
// https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
2.2250738585072011e-308,

// https://github.com/golang/go/issues/29491
//498484681984085570,
//-5.8339553793802237e+23,
}

func TestFormatFloat64(t *testing.T) {
Expand Down
13 changes: 13 additions & 0 deletions tables.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 463ddad

Please sign in to comment.