internal/number: implement more formatting
- simplified API
- use MinExpDigits to determine whether to use
scientific or decimal.
- test added to verify that this is correct.
- reuse percent pattern for permille:
- use DigitShift instead of Multiplier
- added support for padding
- copy Pattern, instead of using pointer, to allow
tinkering
- small fix for quoting.
Change-Id: Ib83ab28f2cad57e90d73bb30b346ab7845a56333
Reviewed-on: https://go-review.googlesource.com/46157
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/internal/number/decimal.go b/internal/number/decimal.go
index a323ae7..eedc76f 100644
--- a/internal/number/decimal.go
+++ b/internal/number/decimal.go
@@ -275,29 +275,29 @@
d.clear()
f.Convert(d, r)
case float32:
- d.convertFloat64(r, float64(f), 32)
+ d.ConvertFloat(r, float64(f), 32)
case float64:
- d.convertFloat64(r, f, 64)
+ d.ConvertFloat(r, f, 64)
case int:
- d.convertInt(r, signed, uint64(f))
+ d.ConvertInt(r, signed, uint64(f))
case int8:
- d.convertInt(r, signed, uint64(f))
+ d.ConvertInt(r, signed, uint64(f))
case int16:
- d.convertInt(r, signed, uint64(f))
+ d.ConvertInt(r, signed, uint64(f))
case int32:
- d.convertInt(r, signed, uint64(f))
+ d.ConvertInt(r, signed, uint64(f))
case int64:
- d.convertInt(r, signed, uint64(f))
+ d.ConvertInt(r, signed, uint64(f))
case uint:
- d.convertInt(r, unsigned, uint64(f))
+ d.ConvertInt(r, unsigned, uint64(f))
case uint8:
- d.convertInt(r, unsigned, uint64(f))
+ d.ConvertInt(r, unsigned, uint64(f))
case uint16:
- d.convertInt(r, unsigned, uint64(f))
+ d.ConvertInt(r, unsigned, uint64(f))
case uint32:
- d.convertInt(r, unsigned, uint64(f))
+ d.ConvertInt(r, unsigned, uint64(f))
case uint64:
- d.convertInt(r, unsigned, f)
+ d.ConvertInt(r, unsigned, f)
// TODO:
// case string: if produced by strconv, allows for easy arbitrary pos.
@@ -310,13 +310,14 @@
}
}
-func (d *Decimal) convertInt(r *RoundingContext, signed bool, x uint64) {
+// ConvertInt converts an integer to decimals.
+func (d *Decimal) ConvertInt(r *RoundingContext, signed bool, x uint64) {
if r.Increment > 0 {
// TODO: if uint64 is too large, fall back to float64
if signed {
- d.convertFloat64(r, float64(int64(x)), 64)
+ d.ConvertFloat(r, float64(int64(x)), 64)
} else {
- d.convertFloat64(r, float64(x), 64)
+ d.ConvertFloat(r, float64(x), 64)
}
return
}
@@ -329,7 +330,8 @@
d.Exp = int32(len(d.Digits))
}
-func (d *Decimal) convertFloat64(r *RoundingContext, x float64, size int) {
+// ConvertFloat converts a floating point number to decimals.
+func (d *Decimal) ConvertFloat(r *RoundingContext, x float64, size int) {
d.clear()
if math.IsNaN(x) {
d.NaN = true
diff --git a/internal/number/format.go b/internal/number/format.go
index 84903fa..9ceaf04 100755
--- a/internal/number/format.go
+++ b/internal/number/format.go
@@ -6,41 +6,128 @@
import (
"strconv"
+ "unicode/utf8"
"golang.org/x/text/language"
)
// TODO:
-// - public (but internal) API for creating formatters
// - split out the logic that computes the visible digits from the rest of the
// formatting code (needed for plural).
// - grouping of fractions
-// - reuse percent pattern for permille
-// - padding
// Formatter contains all the information needed to render a number.
type Formatter struct {
- *Pattern
+ Pattern
Info
RoundingContext
- f func(dst []byte, f *Formatter, d *Decimal) []byte
}
-func lookupFormat(t language.Tag, tagToIndex []uint8) *Pattern {
+func (f *Formatter) init(t language.Tag, index []uint8) {
+ f.Info = InfoFromTag(t)
for ; ; t = t.Parent() {
if ci, ok := language.CompactIndex(t); ok {
- return &formats[tagToIndex[ci]]
+ f.Pattern = formats[index[ci]]
+ break
}
}
}
-func (f *Formatter) Format(dst []byte, d *Decimal) []byte {
- return f.f(dst, f, d)
+// InitPattern initializes a Formatter for the given Pattern.
+func (f *Formatter) InitPattern(t language.Tag, pat *Pattern) {
+ f.Info = InfoFromTag(t)
+ f.Pattern = *pat
}
-func appendDecimal(dst []byte, f *Formatter, d *Decimal) []byte {
+// InitDecimal initializes a Formatter using the default Pattern for the given
+// language.
+func (f *Formatter) InitDecimal(t language.Tag) {
+ f.init(t, tagToDecimal)
+}
+
+// InitScientific initializes a Formatter using the default Pattern for the
+// given language.
+func (f *Formatter) InitScientific(t language.Tag) {
+ f.init(t, tagToScientific)
+}
+
+// InitEngineering initializes a Formatter using the default Pattern for the
+// given language.
+func (f *Formatter) InitEngineering(t language.Tag) {
+ f.init(t, tagToScientific)
+ f.Pattern.MaxIntegerDigits = 3
+ f.Pattern.MinIntegerDigits = 1
+}
+
+// InitPercent initializes a Formatter using the default Pattern for the given
+// language.
+func (f *Formatter) InitPercent(t language.Tag) {
+ f.init(t, tagToPercent)
+}
+
+// InitPerMille initializes a Formatter using the default Pattern for the given
+// language.
+func (f *Formatter) InitPerMille(t language.Tag) {
+ f.init(t, tagToPercent)
+ f.Pattern.DigitShift = 3
+}
+
+func (f *Formatter) Append(dst []byte, x interface{}) []byte {
+ var d Decimal
+ d.Convert(&f.RoundingContext, x)
+ return f.Format(dst, &d)
+}
+
+func (f *Formatter) Format(dst []byte, d *Decimal) []byte {
+ var result []byte
+ var postPrefix, preSuffix int
+ if f.MinExponentDigits > 0 {
+ result, postPrefix, preSuffix = appendScientific(dst, f, d)
+ } else {
+ result, postPrefix, preSuffix = appendDecimal(dst, f, d)
+ }
+ if f.PadRune == 0 {
+ return result
+ }
+ width := int(f.FormatWidth)
+ if count := utf8.RuneCount(result); count < width {
+ insertPos := 0
+ switch f.Flags & PadMask {
+ case PadAfterPrefix:
+ insertPos = postPrefix
+ case PadBeforeSuffix:
+ insertPos = preSuffix
+ case PadAfterSuffix:
+ insertPos = len(result)
+ }
+ num := width - count
+ pad := [utf8.UTFMax]byte{' '}
+ sz := 1
+ if r := f.PadRune; r != 0 {
+ sz = utf8.EncodeRune(pad[:], r)
+ }
+ extra := sz * num
+ if n := len(result) + extra; n < cap(result) {
+ result = result[:n]
+ copy(result[insertPos+extra:], result[insertPos:])
+ } else {
+ buf := make([]byte, n)
+ copy(buf, result[:insertPos])
+ copy(buf[insertPos+extra:], result[insertPos:])
+ result = buf
+ }
+ for ; num > 0; num-- {
+ insertPos += copy(result[insertPos:], pad[:sz])
+ }
+ }
+ return result
+}
+
+// appendDecimal appends a formatted number to dst. It returns two possible
+// insertion points for padding.
+func appendDecimal(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, preSuf int) {
if dst, ok := f.renderSpecial(dst, d); ok {
- return dst
+ return dst, 0, len(dst)
}
n := d.normalize()
if maxSig := int(f.MaxSignificantDigits); maxSig > 0 {
@@ -48,6 +135,7 @@
}
digits := n.Digits
exp := n.Exp
+ exp += int32(f.Pattern.DigitShift)
// Split in integer and fraction part.
var intDigits, fracDigits []byte
@@ -148,12 +236,14 @@
if len(dst) == savedLen {
dst = f.AppendDigit(dst, 0)
}
- return appendAffix(dst, f, suffix, neg)
+ return appendAffix(dst, f, suffix, neg), savedLen, len(dst)
}
-func appendScientific(dst []byte, f *Formatter, d *Decimal) []byte {
+// appendScientific appends a formatted number to dst. It returns two possible
+// insertion points for padding.
+func appendScientific(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, preSuf int) {
if dst, ok := f.renderSpecial(dst, d); ok {
- return dst
+ return dst, 0, 0
}
// Significant digits are transformed by parser for scientific notation and
// do not need to be handled here.
@@ -244,14 +334,14 @@
dst = append(dst, f.Symbol(SymPlusSign)...)
}
buf := [12]byte{}
- b := strconv.AppendUint(buf[:0], uint64(exp), 10)
+ b = strconv.AppendUint(buf[:0], uint64(exp), 10)
for i := len(b); i < int(f.MinExponentDigits); i++ {
dst = f.AppendDigit(dst, 0)
}
for _, c := range b {
dst = f.AppendDigit(dst, c-'0')
}
- return appendAffix(dst, f, suffix, neg)
+ return appendAffix(dst, f, suffix, neg), savedLen, len(dst)
}
func (f *Formatter) getAffixes(neg bool) (affix, suffix string) {
@@ -307,7 +397,15 @@
escaping = true
case r == '\'':
quoting = !quoting
- case !quoting && (r == '-' || r == '+'):
+ case quoting:
+ dst = append(dst, string(r)...)
+ case r == '%':
+ if f.DigitShift == 3 {
+ dst = append(dst, f.Symbol(SymPerMille)...)
+ } else {
+ dst = append(dst, f.Symbol(SymPercentSign)...)
+ }
+ case r == '-' || r == '+':
if neg {
dst = append(dst, f.Symbol(SymMinusSign)...)
} else {
diff --git a/internal/number/format_test.go b/internal/number/format_test.go
index 355a33a..850ad82 100755
--- a/internal/number/format_test.go
+++ b/internal/number/format_test.go
@@ -7,7 +7,6 @@
import (
"fmt"
"log"
- "strings"
"testing"
"golang.org/x/text/language"
@@ -287,22 +286,139 @@
"12345": "12.34E03",
"123.456": "123.4E00",
},
+ }, {
+ pattern: "@@E0",
+ test: pairs{
+ "0": "0.0E0",
+ "99": "9.9E1",
+ "0.99": "9.9E-1",
+ },
+ }, {
+ pattern: "@###E00",
+ test: pairs{
+ "0": "0E00",
+ "1": "1E00",
+ "11": "1.1E01",
+ "111": "1.11E02",
+ "1111": "1.111E03",
+ "11111": "1.111E04",
+ "0.1": "1E-01",
+ "0.11": "1.1E-01",
+ "0.001": "1E-03",
+ },
+ }, {
+ pattern: "*x###",
+ test: pairs{
+ "0": "xx0",
+ "10": "x10",
+ "100": "100",
+ "1000": "1000",
+ },
+ }, {
+ pattern: "###*x",
+ test: pairs{
+ "0": "0xx",
+ "10": "10x",
+ "100": "100",
+ "1000": "1000",
+ },
+ }, {
+ pattern: "* ###0.000",
+ test: pairs{
+ "0": " 0.000",
+ "123": " 123.000",
+ "123.456": " 123.456",
+ "1234.567": "1234.567",
+ },
+ }, {
+ pattern: "**0.0##E00",
+ test: pairs{
+ "0": "**0.0E00",
+ "10": "**1.0E01",
+ "11": "**1.1E01",
+ "111": "*1.11E02",
+ "1111": "1.111E03",
+ "11111": "1.111E04",
+ "11110": "1.111E04",
+ "11100": "*1.11E04",
+ "11000": "**1.1E04",
+ "10000": "**1.0E04",
+ },
+ }, {
+ pattern: "*xpre#suf",
+ test: pairs{
+ "0": "pre0suf",
+ "10": "pre10suf",
+ },
+ }, {
+ pattern: "*∞ pre #### suf",
+ test: pairs{
+ "0": "∞∞∞ pre 0 suf",
+ "10": "∞∞ pre 10 suf",
+ "100": "∞ pre 100 suf",
+ "1000": " pre 1000 suf",
+ },
+ }, {
+ pattern: "pre *∞#### suf",
+ test: pairs{
+ "0": "pre ∞∞∞0 suf",
+ "10": "pre ∞∞10 suf",
+ "100": "pre ∞100 suf",
+ "1000": "pre 1000 suf",
+ },
+ }, {
+ pattern: "pre ####*∞ suf",
+ test: pairs{
+ "0": "pre 0∞∞∞ suf",
+ "10": "pre 10∞∞ suf",
+ "100": "pre 100∞ suf",
+ "1000": "pre 1000 suf",
+ },
+ }, {
+ pattern: "pre #### suf *∞",
+ test: pairs{
+ "0": "pre 0 suf ∞∞∞",
+ "10": "pre 10 suf ∞∞",
+ "100": "pre 100 suf ∞",
+ "1000": "pre 1000 suf ",
+ },
+ }, {
+ // Take width of positive pattern.
+ pattern: "**####;**-######x",
+ test: pairs{
+ "0": "***0",
+ "-1": "*-1x",
+ },
+ }, {
+ pattern: "0.00%",
+ test: pairs{
+ "0.1": "10.00%",
+ },
+ }, {
+ pattern: "0.##%",
+ test: pairs{
+ "0.1": "10%",
+ "0.11": "11%",
+ "0.111": "11.1%",
+ "0.1111": "11.11%",
+ "0.11111": "11.11%",
+ },
+ }, {
+ pattern: "‰ 0.0#",
+ test: pairs{
+ "0.1": "‰ 100.0",
+ "0.11": "‰ 110.0",
+ "0.111": "‰ 111.0",
+ "0.1111": "‰ 111.1",
+ "0.11111": "‰ 111.11",
+ "0.111111": "‰ 111.11",
+ },
}}
// TODO:
- // "@@E0",
- // "@###E00",
- // "0.0%",
- // "0.0‰",
// "#,##0.00¤",
// "#,##0.00 ¤;(#,##0.00 ¤)",
- // // padding
- // "*x#",
- // "#*x",
- // "*xpre#suf",
- // "pre*x#suf",
- // "pre#*xsuf",
- // "pre#suf*x",
+
for _, tc := range testCases {
pat := tc.pat
if pat == nil {
@@ -311,15 +427,8 @@
log.Fatal(err)
}
}
- f := &Formatter{
- pat,
- InfoFromTag(language.English),
- RoundingContext{},
- appendDecimal,
- }
- if strings.IndexByte(tc.pattern, 'E') != -1 {
- f.f = appendScientific
- }
+ var f Formatter
+ f.InitPattern(language.English, pat)
for dec, want := range tc.test {
buf := make([]byte, 100)
t.Run(tc.pattern+"/"+dec, func(t *testing.T) {
@@ -347,12 +456,36 @@
}
for _, tc := range testCases {
t.Run(fmt.Sprint(tc.tag, "/", tc.num), func(t *testing.T) {
- f := &Formatter{
- lookupFormat(tc.tag, tagToDecimal),
- InfoFromTag(tc.tag),
- RoundingContext{},
- appendDecimal,
+ var f Formatter
+ f.InitDecimal(tc.tag)
+ d := mkdec(tc.num)
+ b := f.Format(nil, &d)
+ if got := string(b); got != tc.want {
+ t.Errorf("got %q; want %q", got, tc.want)
}
+ })
+ }
+}
+
+func TestFormatters(t *testing.T) {
+ var f Formatter
+ testCases := []struct {
+ init func(t language.Tag)
+ num string
+ want string
+ }{
+ {f.InitDecimal, "123456.78", "123,456.78"},
+ {f.InitScientific, "123456.78", "1.23E5"},
+ {f.InitEngineering, "123456.78", "123E3"},
+
+ {f.InitPercent, "0.1234", "12.34%"},
+ {f.InitPerMille, "0.1234", "123.40‰"},
+ }
+ for i, tc := range testCases {
+ t.Run(fmt.Sprint(i, "/", tc.num), func(t *testing.T) {
+ tc.init(language.English)
+ f.Pattern.MinFractionDigits = 2
+ f.Pattern.MaxFractionDigits = 2
d := mkdec(tc.num)
b := f.Format(nil, &d)
if got := string(b); got != tc.want {
diff --git a/internal/number/pattern.go b/internal/number/pattern.go
index 5610c60..8d7f9a6 100644
--- a/internal/number/pattern.go
+++ b/internal/number/pattern.go
@@ -46,11 +46,11 @@
Offset uint16 // Offset into Affix for prefix and suffix
NegOffset uint16 // Offset into Affix for negative prefix and suffix or 0.
- Multiplier uint32
+ FormatWidth uint16
+
RoundIncrement uint32 // Use Min*Digits to determine scale
PadRune rune
-
- FormatWidth uint16
+ DigitShift uint8 // Number of decimals to shift. Used for % and ‰.
GroupingSize [2]uint8
Flags PatternFlag
@@ -247,26 +247,41 @@
'#', '@', '.', '*', ',', ';':
return nil
case '\'':
- return p.escape
+ p.FormatWidth--
+ return p.escapeFirst
case '%':
- if p.Multiplier != 0 {
+ if p.DigitShift != 0 {
p.setError(errDuplicatePercentSign)
}
- p.Multiplier = 100
+ p.DigitShift = 2
case '\u2030': // ‰ Per mille
- if p.Multiplier != 0 {
+ if p.DigitShift != 0 {
p.setError(errDuplicatePermilleSign)
}
- p.Multiplier = 1000
+ p.DigitShift = 3
// TODO: handle currency somehow: ¤, ¤¤, ¤¤¤, ¤¤¤¤
}
p.buf = append(p.buf, string(r)...)
return p.affix
}
+func (p *parser) escapeFirst(r rune) state {
+ switch r {
+ case '\'':
+ p.buf = append(p.buf, "\\'"...)
+ return p.affix
+ default:
+ p.buf = append(p.buf, '\'')
+ p.buf = append(p.buf, string(r)...)
+ }
+ return p.escape
+}
+
func (p *parser) escape(r rune) state {
switch r {
case '\'':
+ p.FormatWidth--
+ p.buf = append(p.buf, '\'')
return p.affix
default:
p.buf = append(p.buf, string(r)...)
diff --git a/internal/number/pattern_test.go b/internal/number/pattern_test.go
index 6adeaf7..97ff64d 100644
--- a/internal/number/pattern_test.go
+++ b/internal/number/pattern_test.go
@@ -114,6 +114,11 @@
MinExponentDigits: 1,
},
}, {
+ // At least one exponent digit is required. As long as this is true, one can
+ // determine that scientific rendering is needed if MinExponentDigits > 0.
+ "#E#",
+ nil,
+}, {
"0E0",
&Pattern{
FormatWidth: 3,
@@ -230,7 +235,7 @@
"0.0%",
&Pattern{
Affix: "\x00\x01%",
- Multiplier: 100,
+ DigitShift: 2,
FormatWidth: 4,
MinIntegerDigits: 1,
MinFractionDigits: 1,
@@ -240,7 +245,7 @@
"0.0‰",
&Pattern{
Affix: "\x00\x03‰",
- Multiplier: 1000,
+ DigitShift: 3,
FormatWidth: 4,
MinIntegerDigits: 1,
MinFractionDigits: 1,
@@ -260,7 +265,7 @@
"#,##0.00 ¤;(#,##0.00 ¤)",
&Pattern{Affix: "\x00\x04\u00a0¤\x01(\x05\u00a0¤)",
NegOffset: 6,
- Multiplier: 0,
+ DigitShift: 0,
FormatWidth: 10,
GroupingSize: [2]uint8{3, 0},
MinIntegerDigits: 1,
@@ -314,6 +319,19 @@
Flags: PadAfterSuffix,
},
}, {
+ `* #0 o''clock`,
+ &Pattern{Affix: "\x00\x09 o\\'clock",
+ FormatWidth: 10,
+ PadRune: 32,
+ MinIntegerDigits: 0x1},
+}, {
+ `'123'* #0'456'`,
+ &Pattern{Affix: "\x05'123'\x05'456'",
+ FormatWidth: 8,
+ PadRune: 32,
+ MinIntegerDigits: 0x1,
+ Flags: PadAfterPrefix},
+}, {
// no duplicate padding
"*xpre#suf*x", nil,
}, {
diff --git a/internal/number/tables.go b/internal/number/tables.go
index 10baa0a..defe95d 100644
--- a/internal/number/tables.go
+++ b/internal/number/tables.go
@@ -846,10 +846,10 @@
var formats = []Pattern{Pattern{Affix: "",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x0,
+ FormatWidth: 0x0,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x0,
+ DigitShift: 0x0,
GroupingSize: [2]uint8{0x0,
0x0},
Flags: 0x0,
@@ -863,10 +863,10 @@
Pattern{Affix: "",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x0,
+ FormatWidth: 0x9,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x9,
+ DigitShift: 0x0,
GroupingSize: [2]uint8{0x3,
0x0},
Flags: 0x0,
@@ -880,10 +880,10 @@
Pattern{Affix: "",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x0,
+ FormatWidth: 0x3,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x3,
+ DigitShift: 0x0,
GroupingSize: [2]uint8{0x0,
0x0},
Flags: 0x0,
@@ -897,10 +897,10 @@
Pattern{Affix: "\x00\x03\u00a0%",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x64,
+ FormatWidth: 0x7,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x7,
+ DigitShift: 0x2,
GroupingSize: [2]uint8{0x3,
0x0},
Flags: 0x0,
@@ -914,10 +914,10 @@
Pattern{Affix: "\x00\x01%",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x64,
+ FormatWidth: 0x6,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x6,
+ DigitShift: 0x2,
GroupingSize: [2]uint8{0x3,
0x0},
Flags: 0x0,
@@ -931,10 +931,10 @@
Pattern{Affix: "",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x0,
+ FormatWidth: 0xc,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0xc,
+ DigitShift: 0x0,
GroupingSize: [2]uint8{0x3,
0x2},
Flags: 0x0,
@@ -948,10 +948,10 @@
Pattern{Affix: "\x00\x01%",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x64,
+ FormatWidth: 0x9,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x9,
+ DigitShift: 0x2,
GroupingSize: [2]uint8{0x3,
0x2},
Flags: 0x0,
@@ -965,10 +965,10 @@
Pattern{Affix: "\x00\x03\u00a0%",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x64,
+ FormatWidth: 0xa,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0xa,
+ DigitShift: 0x2,
GroupingSize: [2]uint8{0x3,
0x2},
Flags: 0x0,
@@ -982,10 +982,10 @@
Pattern{Affix: "",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x0,
+ FormatWidth: 0x9,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x9,
+ DigitShift: 0x0,
GroupingSize: [2]uint8{0x0,
0x0},
Flags: 0x0,
@@ -999,10 +999,10 @@
Pattern{Affix: "",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x0,
+ FormatWidth: 0xd,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0xd,
+ DigitShift: 0x0,
GroupingSize: [2]uint8{0x0,
0x0},
Flags: 0x2,
@@ -1016,10 +1016,10 @@
Pattern{Affix: "\x00\x01%",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x64,
+ FormatWidth: 0x3,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x3,
+ DigitShift: 0x2,
GroupingSize: [2]uint8{0x0,
0x0},
Flags: 0x0,
@@ -1033,10 +1033,10 @@
Pattern{Affix: "\x03%\u00a0\x00",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x64,
+ FormatWidth: 0x7,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x7,
+ DigitShift: 0x2,
GroupingSize: [2]uint8{0x3,
0x0},
Flags: 0x0,
@@ -1050,10 +1050,10 @@
Pattern{Affix: "\x03%\u00a0\x00\x04%\u00a0-\x00",
Offset: 0x0,
NegOffset: 0x5,
- Multiplier: 0x64,
+ FormatWidth: 0x7,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x7,
+ DigitShift: 0x2,
GroupingSize: [2]uint8{0x3,
0x0},
Flags: 0x0,
@@ -1067,10 +1067,10 @@
Pattern{Affix: "\x01[\x01]",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x0,
+ FormatWidth: 0x5,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x5,
+ DigitShift: 0x0,
GroupingSize: [2]uint8{0x0,
0x0},
Flags: 0x0,
@@ -1084,10 +1084,10 @@
Pattern{Affix: "",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x0,
+ FormatWidth: 0x1,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x1,
+ DigitShift: 0x0,
GroupingSize: [2]uint8{0x0,
0x0},
Flags: 0x0,
@@ -1101,10 +1101,10 @@
Pattern{Affix: "\x01%\x00",
Offset: 0x0,
NegOffset: 0x0,
- Multiplier: 0x64,
+ FormatWidth: 0x6,
RoundIncrement: 0x0,
PadRune: 0,
- FormatWidth: 0x6,
+ DigitShift: 0x2,
GroupingSize: [2]uint8{0x3,
0x0},
Flags: 0x0,