Browse Groups

• ## Re: "ocaml_beginners"::[] Conversion of exponent number

(4)
• NextPrevious
• ... Hi Eric, The Num arbitrary-precision library might also be useful if floating-point arithmetic isn t precise enough:
Message 1 of 4 , Dec 1 4:21 PM
View Source
On Thu, 28 Nov 2002, Eric Merritt wrote:

> I actually hadn't thought of that, I guess it would depend on how large
> a number a float may store in ocaml. I will look into it.

Hi Eric,

The 'Num' arbitrary-precision library might also be useful if
floating-point arithmetic isn't precise enough:

http://caml.inria.fr/ocaml/htmlman/manual036.html

For example:

(******)
# open Num;;
# let v = (num_of_string "9453 / 1000") */
(num_of_int 10 **/ num_of_int 23);;
val v : Num.num = Big_int <abstr>
# approx_num_exp 5 v;;
- : string = "+0.94530e24"
(******)

I'm still very new at this Ocaml stuff, so I'm not sure if there's a
function in 'Num' that converts directly from scientific notation to a
Num. But it shouldn't be too hard to cook a toy function up. Here's the
beginnings of such a function:

(******)

(* string_exp_to_num: a toy example of string manipulation in Ocaml.

Danny Yoo (dyoo@...)
*)

let split_mantissa s =
let s = String.lowercase s in
let l = String.length s in
let i = String.index s 'e' in
let sub = String.sub in
(sub s 0 i),
(sub s (i+1) (l-i-1));;

(* Given string s and integer i, returns a new string with 's'
repeated i times. *)
let rec string_multiply s i =
if i = 0 then ""
else if i mod 2 = 0
then string_multiply (s^s) (i/2)
else s ^ string_multiply s (i-1);;

(* Given a decimal string, returns a string that expresses its
ratio.*)
let rec rationalize s =
let i = String.index s '.' in
let l = String.length s in
let denom = "1" ^ (string_multiply "0" (l-i-1)) in
(String.sub s 0 i) ^
(String.sub s (i+1) (String.length s - i - 1))
^ "/" ^ denom
;;

(* int_of_string does not appear to take in unary PLUS, so
this function tries to fix that. *)
let my_int_of_string s =
if String.get s 0 = '+'
then int_of_string (String.sub s 1 ((String.length s)-1))
else int_of_string s;;

let string_exp_to_num s =
let (mantissa, exponent) = split_mantissa s in
let ( * ) = Num.( */ ) in
let ( ** ) = Num. ( **/ ) in
(Num.num_of_string (rationalize mantissa)) *
((Num.num_of_int 10) ** Num.num_of_int (my_int_of_string exponent))
;;

(******)

This code is not bulletproof yet; I don't take into account things such as
missing exponents or decimal points, but that should be pretty easy to
patch up. It's also probably a bit ugly because I'm still learning the
language.

I would have expected such a function to exist in the standard library,
since there's already a Num.approx_num_exp function that does the inverse
operation of turning a num into a string, but I don't know enough of Ocaml
yet.

Good luck!
Your message has been successfully submitted and would be delivered to recipients shortly.
• Changes have not been saved
Press OK to abandon changes or Cancel to continue editing
• Your browser is not supported
Kindly note that Groups does not support 7.0 or earlier versions of Internet Explorer. We recommend upgrading to the latest Internet Explorer, Google Chrome, or Firefox. If you are using IE 9 or later, make sure you turn off Compatibility View.