1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
9 // ErrRange indicates that a value is out of range for the target type.
10 var ErrRange
= errors
.New("value out of range")
12 // ErrSyntax indicates that a value does not have the right syntax for the target type.
13 var ErrSyntax
= errors
.New("invalid syntax")
15 // A NumError records a failed conversion.
16 type NumError
struct {
17 Func
string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
18 Num
string // the input
19 Err error
// the reason the conversion failed (ErrRange, ErrSyntax)
22 func (e
*NumError
) Error() string {
23 return "strconv." + e
.Func
+ ": " + `parsing "` + e
.Num
+ `": ` + e
.Err
.Error()
26 func syntaxError(fn
, str
string) *NumError
{
27 return &NumError
{fn
, str
, ErrSyntax
}
30 func rangeError(fn
, str
string) *NumError
{
31 return &NumError
{fn
, str
, ErrRange
}
34 const intSize
= 32 << uint(^uint(0)>>63)
36 const IntSize
= intSize
// number of bits in int, uint (32 or 64)
38 // Return the first number n such that n*base >= 1<<64.
39 func cutoff64(base
int) uint64 {
43 return (1<<64-1)/uint64(base
) + 1
46 // ParseUint is like ParseInt but for unsigned numbers.
47 func ParseUint(s
string, base
int, bitSize
int) (n
uint64, err error
) {
48 var cutoff
, maxVal
uint64
51 bitSize
= int(IntSize
)
60 case 2 <= base
&& base
<= 36:
61 // valid base; nothing to do
64 // Look for octal, hex prefix.
66 case s
[0] == '0' && len(s
) > 1 && (s
[1] == 'x' || s
[1] == 'X'):
80 err
= errors
.New("invalid base " + Itoa(base
))
85 cutoff
= cutoff64(base
)
86 maxVal
= 1<<uint(bitSize
) - 1
88 for i
:= 0; i
< len(s
); i
++ {
92 case '0' <= d
&& d
<= '9':
94 case 'a' <= d
&& d
<= 'z':
96 case 'A' <= d
&& d
<= 'Z':
118 if n1
< n || n1
> maxVal
{
130 return n
, &NumError
{"ParseUint", s0
, err
}
133 // ParseInt interprets a string s in the given base (2 to 36) and
134 // returns the corresponding value i. If base == 0, the base is
135 // implied by the string's prefix: base 16 for "0x", base 8 for
136 // "0", and base 10 otherwise.
138 // The bitSize argument specifies the integer type
139 // that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
140 // correspond to int, int8, int16, int32, and int64.
142 // The errors that ParseInt returns have concrete type *NumError
143 // and include err.Num = s. If s is empty or contains invalid
144 // digits, err.Error = ErrSyntax; if the value corresponding
145 // to s cannot be represented by a signed integer of the
146 // given size, err.Error = ErrRange.
147 func ParseInt(s
string, base
int, bitSize
int) (i
int64, err error
) {
148 const fnParseInt
= "ParseInt"
151 bitSize
= int(IntSize
)
156 return 0, syntaxError(fnParseInt
, s
)
159 // Pick off leading sign.
164 } else if s
[0] == '-' {
169 // Convert unsigned and check range.
171 un
, err
= ParseUint(s
, base
, bitSize
)
172 if err
!= nil && err
.(*NumError
).Err
!= ErrRange
{
173 err
.(*NumError
).Func
= fnParseInt
174 err
.(*NumError
).Num
= s0
177 cutoff
:= uint64(1 << uint(bitSize
-1))
178 if !neg
&& un
>= cutoff
{
179 return int64(cutoff
- 1), rangeError(fnParseInt
, s0
)
181 if neg
&& un
> cutoff
{
182 return -int64(cutoff
), rangeError(fnParseInt
, s0
)
191 // Atoi is shorthand for ParseInt(s, 10, 0).
192 func Atoi(s
string) (i
int, err error
) {
193 i64
, err
:= ParseInt(s
, 10, 0)