diff options
author | Gabriel Scherer <gabriel.scherer@gmail.com> | 2013-08-04 19:58:03 +0000 |
---|---|---|
committer | Gabriel Scherer <gabriel.scherer@gmail.com> | 2013-08-04 19:58:03 +0000 |
commit | 2c990bacc0f9442cca2ed381877b57b65b25576f (patch) | |
tree | 9c3d0a253a1aaa7e57c09a6f14d301f1ded00612 /otherlibs | |
parent | 8564a6e8c444a3d0b0b27f9b1f4e70d7041f1fe6 (diff) | |
download | ocaml-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.ml | 21 | ||||
-rw-r--r-- | otherlibs/num/nat.ml | 2 |
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; |