mirror of
https://github.com/golang/go
synced 2024-11-13 17:00:22 -07:00
allow hex, octal in Atoi, etc.
R=r DELTA=169 (79 added, 23 deleted, 67 changed) OCL=25079 CL=25083
This commit is contained in:
parent
9e3e61627d
commit
eb3823a44d
@ -14,51 +14,87 @@ func computeIntsize() uint {
|
|||||||
}
|
}
|
||||||
var intsize = computeIntsize();
|
var intsize = computeIntsize();
|
||||||
|
|
||||||
// Convert decimal string to unsigned integer.
|
// Return the first number n such that n*base >= 1<<64.
|
||||||
func Atoui64(s string) (i uint64, err *os.Error) {
|
func cutoff64(base int) uint64 {
|
||||||
// empty string bad
|
if base < 2 {
|
||||||
if len(s) == 0 {
|
return 0;
|
||||||
return 0, os.EINVAL
|
}
|
||||||
|
return (1<<64 - 1) / uint64(base) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pick off zero
|
// Convert arbitrary base string to unsigned integer.
|
||||||
if s == "0" {
|
func Btoui64(base int, s string) (n uint64, err *os.Error) {
|
||||||
return 0, nil
|
if base < 2 || base > 36 || len(s) < 1 {
|
||||||
|
return 0, os.EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, leading zero bad:
|
n = 0;
|
||||||
// don't want to take something intended as octal.
|
cutoff := cutoff64(base);
|
||||||
if s[0] == '0' {
|
|
||||||
return 0, os.EINVAL
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse number
|
|
||||||
n := uint64(0);
|
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
if s[i] < '0' || s[i] > '9' {
|
var v byte;
|
||||||
return 0, os.EINVAL
|
switch {
|
||||||
|
case '0' <= s[i] && s[i] <= '9':
|
||||||
|
v = s[i] - '0';
|
||||||
|
case 'a' <= s[i] && s[i] <= 'z':
|
||||||
|
v = s[i] - 'a' + 10;
|
||||||
|
case 'A' <= s[i] && s[i] <= 'Z':
|
||||||
|
v = s[i] - 'A' + 10;
|
||||||
|
default:
|
||||||
|
return 0, os.EINVAL;
|
||||||
}
|
}
|
||||||
if n > (1<<64)/10 {
|
if int(v) >= base {
|
||||||
return 1<<64-1, os.ERANGE
|
return 0, os.EINVAL;
|
||||||
}
|
|
||||||
n = n*10;
|
|
||||||
d := uint64(s[i] - '0');
|
|
||||||
if n+d < n {
|
|
||||||
return 1<<64-1, os.ERANGE
|
|
||||||
}
|
|
||||||
n += d;
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert decimal string to integer.
|
if n >= cutoff {
|
||||||
func Atoi64(s string) (i int64, err *os.Error) {
|
// n*base overflows
|
||||||
// empty string bad
|
return 1<<64-1, os.ERANGE;
|
||||||
|
}
|
||||||
|
n *= uint64(base);
|
||||||
|
|
||||||
|
n1 := n+uint64(v);
|
||||||
|
if n1 < n {
|
||||||
|
// n+v overflows
|
||||||
|
return 1<<64-1, os.ERANGE;
|
||||||
|
}
|
||||||
|
n = n1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Convert string to uint64.
|
||||||
|
// Use standard prefixes to signal octal, hexadecimal.
|
||||||
|
func Atoui64(s string) (i uint64, err *os.Error) {
|
||||||
|
// Empty string bad.
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return 0, os.EINVAL
|
return 0, os.EINVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
// pick off leading sign
|
// Look for octal, hex prefix.
|
||||||
|
if s[0] == '0' && len(s) > 1 {
|
||||||
|
if s[1] == 'x' || s[1] == 'X' {
|
||||||
|
// hex
|
||||||
|
return Btoui64(16, s[2:len(s)]);
|
||||||
|
}
|
||||||
|
// octal
|
||||||
|
return Btoui64(8, s[1:len(s)]);
|
||||||
|
}
|
||||||
|
// decimal
|
||||||
|
return Btoui64(10, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert string to int64.
|
||||||
|
// Use standard prefixes to signal octal, hexadecimal.
|
||||||
|
func Atoi64(s string) (i int64, err *os.Error) {
|
||||||
|
// Empty string bad.
|
||||||
|
if len(s) == 0 {
|
||||||
|
return 0, os.EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pick off leading sign.
|
||||||
neg := false;
|
neg := false;
|
||||||
if s[0] == '+' {
|
if s[0] == '+' {
|
||||||
s = s[1:len(s)]
|
s = s[1:len(s)]
|
||||||
@ -67,6 +103,7 @@ func Atoi64(s string) (i int64, err *os.Error) {
|
|||||||
s = s[1:len(s)]
|
s = s[1:len(s)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert unsigned and check range.
|
||||||
var un uint64;
|
var un uint64;
|
||||||
un, err = Atoui64(s);
|
un, err = Atoui64(s);
|
||||||
if err != nil && err != os.ERANGE {
|
if err != nil && err != os.ERANGE {
|
||||||
@ -85,6 +122,8 @@ func Atoi64(s string) (i int64, err *os.Error) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert string to uint.
|
||||||
|
// Use standard prefixes to signal octal, hexadecimal.
|
||||||
func Atoui(s string) (i uint, err *os.Error) {
|
func Atoui(s string) (i uint, err *os.Error) {
|
||||||
i1, e1 := Atoui64(s);
|
i1, e1 := Atoui64(s);
|
||||||
if e1 != nil && e1 != os.ERANGE {
|
if e1 != nil && e1 != os.ERANGE {
|
||||||
@ -99,6 +138,8 @@ func Atoui(s string) (i uint, err *os.Error) {
|
|||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert string to int.
|
||||||
|
// Use standard prefixes to signal octal, hexadecimal.
|
||||||
func Atoi(s string) (i int, err *os.Error) {
|
func Atoi(s string) (i int, err *os.Error) {
|
||||||
i1, e1 := Atoi64(s);
|
i1, e1 := Atoi64(s);
|
||||||
if e1 != nil && e1 != os.ERANGE {
|
if e1 != nil && e1 != os.ERANGE {
|
||||||
|
@ -3,9 +3,10 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package strconv
|
package strconv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os";
|
|
||||||
"fmt";
|
"fmt";
|
||||||
|
"os";
|
||||||
"strconv";
|
"strconv";
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -21,12 +22,20 @@ var atoui64tests = []atoui64Test (
|
|||||||
atoui64Test("0", 0, nil),
|
atoui64Test("0", 0, nil),
|
||||||
atoui64Test("1", 1, nil),
|
atoui64Test("1", 1, nil),
|
||||||
atoui64Test("12345", 12345, nil),
|
atoui64Test("12345", 12345, nil),
|
||||||
atoui64Test( "012345", 0, os.EINVAL ),
|
atoui64Test("012345", 012345, nil),
|
||||||
|
atoui64Test("0x12345", 0x12345, nil),
|
||||||
|
atoui64Test("0X12345", 0x12345, nil),
|
||||||
atoui64Test("12345x", 0, os.EINVAL),
|
atoui64Test("12345x", 0, os.EINVAL),
|
||||||
atoui64Test("98765432100", 98765432100, nil),
|
atoui64Test("98765432100", 98765432100, nil),
|
||||||
atoui64Test("18446744073709551615", 1<<64-1, nil),
|
atoui64Test("18446744073709551615", 1<<64-1, nil),
|
||||||
atoui64Test("18446744073709551616", 1<<64-1, os.ERANGE),
|
atoui64Test("18446744073709551616", 1<<64-1, os.ERANGE),
|
||||||
atoui64Test("18446744073709551620", 1<<64-1, os.ERANGE),
|
atoui64Test("18446744073709551620", 1<<64-1, os.ERANGE),
|
||||||
|
atoui64Test("0xFFFFFFFFFFFFFFFF", 1<<64-1, nil),
|
||||||
|
atoui64Test("0x10000000000000000", 1<<64-1, os.ERANGE),
|
||||||
|
atoui64Test("01777777777777777777777", 1<<64-1, nil),
|
||||||
|
atoui64Test("01777777777777777777778", 0, os.EINVAL),
|
||||||
|
atoui64Test("02000000000000000000000", 1<<64-1, os.ERANGE),
|
||||||
|
atoui64Test("0200000000000000000000", 1<<61, nil),
|
||||||
)
|
)
|
||||||
|
|
||||||
type atoi64Test struct {
|
type atoi64Test struct {
|
||||||
@ -43,8 +52,10 @@ var atoi64test = []atoi64Test (
|
|||||||
atoi64Test("-1", -1, nil),
|
atoi64Test("-1", -1, nil),
|
||||||
atoi64Test("12345", 12345, nil),
|
atoi64Test("12345", 12345, nil),
|
||||||
atoi64Test("-12345", -12345, nil),
|
atoi64Test("-12345", -12345, nil),
|
||||||
atoi64Test( "012345", 0, os.EINVAL ),
|
atoi64Test("012345", 012345, nil),
|
||||||
atoi64Test( "-012345", 0, os.EINVAL ),
|
atoi64Test("-012345", -012345, nil),
|
||||||
|
atoi64Test("0x12345", 0x12345, nil),
|
||||||
|
atoi64Test("-0X12345", -0x12345, nil),
|
||||||
atoi64Test("12345x", 0, os.EINVAL),
|
atoi64Test("12345x", 0, os.EINVAL),
|
||||||
atoi64Test("-12345x", 0, os.EINVAL),
|
atoi64Test("-12345x", 0, os.EINVAL),
|
||||||
atoi64Test("98765432100", 98765432100, nil),
|
atoi64Test("98765432100", 98765432100, nil),
|
||||||
@ -68,7 +79,9 @@ var atoui32tests = []atoui32Test (
|
|||||||
atoui32Test("0", 0, nil),
|
atoui32Test("0", 0, nil),
|
||||||
atoui32Test("1", 1, nil),
|
atoui32Test("1", 1, nil),
|
||||||
atoui32Test("12345", 12345, nil),
|
atoui32Test("12345", 12345, nil),
|
||||||
atoui32Test( "012345", 0, os.EINVAL ),
|
atoui32Test("012345", 012345, nil),
|
||||||
|
atoui32Test("0x12345", 0x12345, nil),
|
||||||
|
atoui32Test("0X12345", 0x12345, nil),
|
||||||
atoui32Test("12345x", 0, os.EINVAL),
|
atoui32Test("12345x", 0, os.EINVAL),
|
||||||
atoui32Test("987654321", 987654321, nil),
|
atoui32Test("987654321", 987654321, nil),
|
||||||
atoui32Test("4294967295", 1<<32-1, nil),
|
atoui32Test("4294967295", 1<<32-1, nil),
|
||||||
@ -89,8 +102,10 @@ var atoi32tests = []atoi32Test (
|
|||||||
atoi32Test("-1", -1, nil),
|
atoi32Test("-1", -1, nil),
|
||||||
atoi32Test("12345", 12345, nil),
|
atoi32Test("12345", 12345, nil),
|
||||||
atoi32Test("-12345", -12345, nil),
|
atoi32Test("-12345", -12345, nil),
|
||||||
atoi32Test( "012345", 0, os.EINVAL ),
|
atoi32Test("012345", 012345, nil),
|
||||||
atoi32Test( "-012345", 0, os.EINVAL ),
|
atoi32Test("-012345", -012345, nil),
|
||||||
|
atoi32Test("0x12345", 0x12345, nil),
|
||||||
|
atoi32Test("-0X12345", -0x12345, nil),
|
||||||
atoi32Test("12345x", 0, os.EINVAL),
|
atoi32Test("12345x", 0, os.EINVAL),
|
||||||
atoi32Test("-12345x", 0, os.EINVAL),
|
atoi32Test("-12345x", 0, os.EINVAL),
|
||||||
atoi32Test("987654321", 987654321, nil),
|
atoi32Test("987654321", 987654321, nil),
|
||||||
|
Loading…
Reference in New Issue
Block a user