summaryrefslogtreecommitdiff
path: root/otherlibs
diff options
context:
space:
mode:
authorGabriel Scherer <gabriel.scherer@gmail.com>2013-08-04 19:58:03 +0000
committerGabriel Scherer <gabriel.scherer@gmail.com>2013-08-04 19:58:03 +0000
commit2c990bacc0f9442cca2ed381877b57b65b25576f (patch)
tree9c3d0a253a1aaa7e57c09a6f14d301f1ded00612 /otherlibs
parent8564a6e8c444a3d0b0b27f9b1f4e70d7041f1fe6 (diff)
downloadocaml-2c990bacc0f9442cca2ed381877b57b65b25576f.tar.gz
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
Diffstat (limited to 'otherlibs')
-rw-r--r--otherlibs/num/big_int.ml21
-rw-r--r--otherlibs/num/nat.ml2
2 files changed, 18 insertions, 5 deletions
diff --git a/otherlibs/num/big_int.ml b/otherlibs/num/big_int.ml
index 95c6f6a8a9..6b5249641e 100644
--- a/otherlibs/num/big_int.ml
+++ b/otherlibs/num/big_int.ml
@@ -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 =
diff --git a/otherlibs/num/nat.ml b/otherlibs/num/nat.ml
index 297a0117c3..2c7e7a91c6 100644
--- a/otherlibs/num/nat.ml
+++ b/otherlibs/num/nat.ml
@@ -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;