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

Expand Messages
• ... 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, 2002
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.