- Dec 1, 2002On Thu, 28 Nov 2002, Eric Merritt wrote:

> I actually hadn't thought of that, I guess it would depend on how large

Hi Eric,

> a number a float may store in ocaml. I will look into it.

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:

(******)

# #load "nums.cma";;

# 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@...)

*)

#load "nums.cma"

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! - << Previous post in topic