Loading ...
Sorry, an error occurred while loading the content.

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

Expand Messages
  • Danny Yoo
    ... 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:


      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
      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

      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

      Good luck!
    Your message has been successfully submitted and would be delivered to recipients shortly.