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 " + Quote(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(0) >> 63)
36 // IntSize is the size in bits of an int or uint value.
37 const IntSize
= intSize
39 const maxUint64
= (1<<64 - 1)
41 // ParseUint is like ParseInt but for unsigned numbers.
42 func ParseUint(s
string, base
int, bitSize
int) (uint64, error
) {
45 var cutoff
, maxVal
uint64
48 bitSize
= int(IntSize
)
57 case 2 <= base
&& base
<= 36:
58 // valid base; nothing to do
61 // Look for octal, hex prefix.
63 case s
[0] == '0' && len(s
) > 1 && (s
[1] == 'x' || s
[1] == 'X'):
78 err
= errors
.New("invalid base " + Itoa(base
))
82 // Cutoff is the smallest number such that cutoff*base > maxUint64.
83 // Use compile-time constants for common cases.
86 cutoff
= maxUint64
/10 + 1
88 cutoff
= maxUint64
/16 + 1
90 cutoff
= maxUint64
/uint64(base
) + 1
93 maxVal
= 1<<uint(bitSize
) - 1
95 for ; i
< len(s
); i
++ {
99 case '0' <= d
&& d
<= '9':
101 case 'a' <= d
&& d
<= 'z':
103 case 'A' <= d
&& d
<= 'Z':
125 if n1
< n || n1
> maxVal
{
137 return n
, &NumError
{"ParseUint", s
, err
}
140 // ParseInt interprets a string s in the given base (2 to 36) and
141 // returns the corresponding value i. If base == 0, the base is
142 // implied by the string's prefix: base 16 for "0x", base 8 for
143 // "0", and base 10 otherwise.
145 // The bitSize argument specifies the integer type
146 // that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
147 // correspond to int, int8, int16, int32, and int64.
149 // The errors that ParseInt returns have concrete type *NumError
150 // and include err.Num = s. If s is empty or contains invalid
151 // digits, err.Err = ErrSyntax and the returned value is 0;
152 // if the value corresponding to s cannot be represented by a
153 // signed integer of the given size, err.Err = ErrRange and the
154 // returned value is the maximum magnitude integer of the
155 // appropriate bitSize and sign.
156 func ParseInt(s
string, base
int, bitSize
int) (i
int64, err error
) {
157 const fnParseInt
= "ParseInt"
160 bitSize
= int(IntSize
)
165 return 0, syntaxError(fnParseInt
, s
)
168 // Pick off leading sign.
173 } else if s
[0] == '-' {
178 // Convert unsigned and check range.
180 un
, err
= ParseUint(s
, base
, bitSize
)
181 if err
!= nil && err
.(*NumError
).Err
!= ErrRange
{
182 err
.(*NumError
).Func
= fnParseInt
183 err
.(*NumError
).Num
= s0
186 cutoff
:= uint64(1 << uint(bitSize
-1))
187 if !neg
&& un
>= cutoff
{
188 return int64(cutoff
- 1), rangeError(fnParseInt
, s0
)
190 if neg
&& un
> cutoff
{
191 return -int64(cutoff
), rangeError(fnParseInt
, s0
)
200 // Atoi returns the result of ParseInt(s, 10, 0) converted to type int.
201 func Atoi(s
string) (int, error
) {
202 const fnAtoi
= "Atoi"
203 i64
, err
:= ParseInt(s
, 10, 0)
204 if nerr
, ok
:= err
.(*NumError
); ok
{