PR#4323: have "of_string" in Num and Big_int work with binary and hexa representations [patch by zoep]

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@13970 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
master
Gabriel Scherer 2013-08-04 19:58:03 +00:00
parent 8564a6e8c4
commit 2c990bacc0
6 changed files with 48 additions and 7 deletions

View File

@ -15,6 +15,7 @@ Standard library:
Features wishes:
- PR#4243: make the Makefiles parallelizable
- PR#4323: have "of_string" in Num and Big_int work with binary and hexa representations (patch by zoep)
OCaml 4.01.0:

View File

@ -419,19 +419,30 @@ let string_of_big_int bi =
else string_of_nat bi.abs_value
let sys_big_int_of_string_aux s ofs len sgn =
let sys_big_int_of_string_aux s ofs len sgn base =
if len < 1 then failwith "sys_big_int_of_string";
let n = sys_nat_of_string 10 s ofs len in
let n = sys_nat_of_string base s ofs len in
if is_zero_nat n 0 (length_nat n) then zero_big_int
else {sign = sgn; abs_value = n}
;;
let sys_big_int_of_string_base s ofs len sgn =
if len < 1 then failwith "sys_big_int_of_string";
if len < 2 then sys_big_int_of_string_aux s ofs len sgn 10
else
match (s.[ofs], s.[ofs+1]) with
| ('0', 'x') | ('0', 'X') -> sys_big_int_of_string_aux s (ofs+2) (len-2) sgn 16
| ('0', 'o') | ('0', 'O') -> sys_big_int_of_string_aux s (ofs+2) (len-2) sgn 8
| ('0', 'b') | ('0', 'B') -> sys_big_int_of_string_aux s (ofs+2) (len-2) sgn 2
| _ -> sys_big_int_of_string_aux s ofs len sgn 10
;;
let sys_big_int_of_string s ofs len =
if len < 1 then failwith "sys_big_int_of_string";
match s.[ofs] with
| '-' -> sys_big_int_of_string_aux s (ofs+1) (len-1) (-1)
| '+' -> sys_big_int_of_string_aux s (ofs+1) (len-1) 1
| _ -> sys_big_int_of_string_aux s ofs len 1
| '-' -> sys_big_int_of_string_base s (ofs+1) (len-1) (-1)
| '+' -> sys_big_int_of_string_base s (ofs+1) (len-1) 1
| _ -> sys_big_int_of_string_base s ofs len 1
;;
let big_int_of_string s =

View File

@ -509,6 +509,7 @@ let base_digit_of_char c base =
let n = Char.code c in
if n >= 48 && n <= 47 + min base 10 then n - 48
else if n >= 65 && n <= 65 + base - 11 then n - 55
else if n >= 97 && n <= 97 + base - 11 then n - 87
else failwith "invalid digit"
(*
@ -537,6 +538,7 @@ let sys_nat_of_string base s off len =
let c = String.get s i in
begin match c with
' ' | '\t' | '\n' | '\r' | '\\' -> ()
| '_' when i > off -> ()
| _ -> int := !int * base + base_digit_of_char c base;
incr digits_read
end;

View File

@ -44,7 +44,7 @@ is_int_big_int
sys_string_of_big_int
1...
big_int_of_string
1... 2... 4... 5... 6... 7... 9... 10...
1... 2... 4... 5... 6... 7... 9... 10... 18... 19... 20... 21...
power_base_int
1... 2... 3...
base_power_big_int
@ -156,7 +156,7 @@ is_integer_num
num_of_ratio
1... 2... 3...
num_of_string
1... 7... 8... 11...
1... 7... 8... 11... 12... 13... 14... 15...
output_value/input_value on nats
1... 2... 3... 4... 5... 6... 7...
output_value/input_value on big ints

View File

@ -447,6 +447,18 @@ eq_big_int (minus_big_int bi1,
(big_int_of_string "-0.02e2")))*)
;;
test 18
eq_big_int (big_int_of_string "0xAbC", big_int_of_int 0xABC);;
test 19
eq_big_int (big_int_of_string "-0o452", big_int_of_int (-0o452));;
test 20
eq_big_int (big_int_of_string "0B110101", big_int_of_int 53);;
test 21
eq_big_int (big_int_of_string "0b11_01_01", big_int_of_int 53);;
testing_function "power_base_int";;
test 1

View File

@ -188,6 +188,21 @@ eq_num (num_of_string "0.23", Ratio (ratio_of_string "0.23/1"));;
failwith_test 11
num_of_string ("frlshjkurty") (Failure "num_of_string");;
test 12
eq_num (num_of_string "0xAbCdEf",
Big_int (big_int_of_int 0xabcdef));;
test 13
eq_num (num_of_string "0b1101/0O1765",
Ratio (ratio_of_string "0b1101/0o1765"));;
test 14
eq_num (num_of_string "-12_34_56",
Big_int (big_int_of_int (-123456)));;
test 15
eq_num (num_of_string "0B101010", Big_int (big_int_of_int 42));;
(*******
testing_function "immediate numbers";;