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 // Return the first number n such that n*base >= 1<<64.
40 func cutoff64(base
int) uint64 {
44 return (1<<64-1)/uint64(base
) + 1
47 // ParseUint is like ParseInt but for unsigned numbers.
48 func ParseUint(s
string, base
int, bitSize
int) (n
uint64, err error
) {
49 var cutoff
, maxVal
uint64
52 bitSize
= int(IntSize
)
61 case 2 <= base
&& base
<= 36:
62 // valid base; nothing to do
65 // Look for octal, hex prefix.
67 case s
[0] == '0' && len(s
) > 1 && (s
[1] == 'x' || s
[1] == 'X'):
81 err
= errors
.New("invalid base " + Itoa(base
))
86 cutoff
= cutoff64(base
)
87 maxVal
= 1<<uint(bitSize
) - 1
89 for i
:= 0; i
< len(s
); i
++ {
93 case '0' <= d
&& d
<= '9':
95 case 'a' <= d
&& d
<= 'z':
97 case 'A' <= d
&& d
<= 'Z':
119 if n1
< n || n1
> maxVal
{
131 return n
, &NumError
{"ParseUint", s0
, err
}
134 // ParseInt interprets a string s in the given base (2 to 36) and
135 // returns the corresponding value i. If base == 0, the base is
136 // implied by the string's prefix: base 16 for "0x", base 8 for
137 // "0", and base 10 otherwise.
139 // The bitSize argument specifies the integer type
140 // that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
141 // correspond to int, int8, int16, int32, and int64.
143 // The errors that ParseInt returns have concrete type *NumError
144 // and include err.Num = s. If s is empty or contains invalid
145 // digits, err.Err = ErrSyntax and the returned value is 0;
146 // if the value corresponding to s cannot be represented by a
147 // signed integer of the given size, err.Err = ErrRange and the
148 // returned value is the maximum magnitude integer of the
149 // appropriate bitSize and sign.
150 func ParseInt(s
string, base
int, bitSize
int) (i
int64, err error
) {
151 const fnParseInt
= "ParseInt"
154 bitSize
= int(IntSize
)
159 return 0, syntaxError(fnParseInt
, s
)
162 // Pick off leading sign.
167 } else if s
[0] == '-' {
172 // Convert unsigned and check range.
174 un
, err
= ParseUint(s
, base
, bitSize
)
175 if err
!= nil && err
.(*NumError
).Err
!= ErrRange
{
176 err
.(*NumError
).Func
= fnParseInt
177 err
.(*NumError
).Num
= s0
180 cutoff
:= uint64(1 << uint(bitSize
-1))
181 if !neg
&& un
>= cutoff
{
182 return int64(cutoff
- 1), rangeError(fnParseInt
, s0
)
184 if neg
&& un
> cutoff
{
185 return -int64(cutoff
), rangeError(fnParseInt
, s0
)
194 // Atoi is shorthand for ParseInt(s, 10, 0).
195 func Atoi(s
string) (i
int, err error
) {
196 i64
, err
:= ParseInt(s
, 10, 0)