caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Marek Kubica <marek@xivilization.net>
To: caml-list@inria.fr
Subject: Re: [Caml-list] Divide and print with precision
Date: Mon, 20 Oct 2014 23:16:25 +0200	[thread overview]
Message-ID: <20141020231625.1fc5224a@xivilization.net> (raw)
In-Reply-To: <543ED84D.4010302@etorok.net>

Hello Török,

Sorry, I somehow missed your reply.

On Wed, 15 Oct 2014 23:25:49 +0300
Török Edwin <edwin+ml-ocaml@etorok.net> wrote:

> This uses Gmp.default_prec (120 bits by default) for the conversion.
> 
> So if you want to use Gmp.F I think you have to specify the ~prec
> otherwise you might loose digits in the znum or zden conversion
> already:
> 
>   let znum = Gmp.F.from_string_prec_base ~prec ~base:10 (Z.to_string
> num) in let zden = Gmp.F.from_string_prec_base ~prec ~base:10
> (Z.to_string den) in let f = Gmp.F.div_prec ~prec znum zden in
>   Gmp.F.to_string_base_digits ~base:10 ~digits:0 f
> 
> Another possibility is to use from_q_prec. I would've used
> Gmp.Q.from_q_prec except for some odd reason it takes a Z.t instead
> of a Q.t, so here is the code that uses Gmp.FR.from_q_prec:
> 
> let string_of_q_prec num den =
>   let znum = Gmp.Z.from_string (Z.to_string num) in
>   let zden = Gmp.Z.from_string (Z.to_string den) in
>   let f = Gmp.FR.from_q_prec ~prec ~mode (Gmp.Q.from_zs znum zden) in
>   Gmp.FR.to_string_base_digits ~mode ~base:10 ~digits:0 f

Thank you, that worked and outputs a lot of digits which is "good
enough" for me. Great!

For the record, here's the complete program:

let prec = 1_000_000
let max_n = 205_211
let mode = Gmp.GMP_RNDN

let euler_fraction n =
  let open Z in
  let numerator = ref one in
  let denominator = ref one in
  for i = 1 to n do
    numerator := succ (!numerator * (of_int i));
    denominator := (of_int i) * !denominator;
  done;
  (!numerator, !denominator)

let f () =
  let (num, den) = euler_fraction max_n in
  let znum = Gmp.Z.from_string @@ Z.to_string num in
  let zden = Gmp.Z.from_string @@ Z.to_string den in
  let euler = Gmp.FR.from_q_prec ~mode ~prec @@ Gmp.Q.from_zs znum zden
in
  print_endline @@ Gmp.FR.to_string_base_digits ~mode ~base:10
~digits:0 euler

let () = f ()

> I don't really like going through string to convert from Z.t to
> Gmp.Z.t, there ought to be a more efficient way.

Neither do I, but I suppose I'd need a C stub to take the Z.t value
(which if I understand Zarith correctly can be a GMP value, but for
small values isn't) and convert it into a Gmp.Z.t. But for such a
simple program and a constant amount of conversions, its not really
worth it.

regards,
Marek

      reply	other threads:[~2014-10-20 21:19 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-15  9:22 Marek Kubica
2014-10-15 10:41 ` Drup
2014-10-15 11:13   ` Marek Kubica
2014-10-15 20:25 ` Török Edwin
2014-10-20 21:16   ` Marek Kubica [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20141020231625.1fc5224a@xivilization.net \
    --to=marek@xivilization.net \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).