From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 0523982355 for ; Tue, 28 Nov 2017 10:16:48 +0100 (CET) Authentication-Results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=andrej.bauer@andrej.com; spf=None smtp.mailfrom=andrej.bauer@andrej.com; spf=None smtp.helo=postmaster@mail-yw0-f181.google.com Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of andrej.bauer@andrej.com) identity=pra; client-ip=209.85.161.181; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="andrej.bauer@andrej.com"; x-sender="andrej.bauer@andrej.com"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of andrej.bauer@andrej.com) identity=mailfrom; client-ip=209.85.161.181; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="andrej.bauer@andrej.com"; x-sender="andrej.bauer@andrej.com"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-yw0-f181.google.com) identity=helo; client-ip=209.85.161.181; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="andrej.bauer@andrej.com"; x-sender="postmaster@mail-yw0-f181.google.com"; x-conformance=sidf_compatible IronPort-PHdr: =?us-ascii?q?9a23=3AAsTu4BFAiqE2i6EkcL8Bap1GYnF86YWxBRYc798d?= =?us-ascii?q?s5kLTJ76r8+wAkXT6L1XgUPTWs2DsrQf1LqQ7viocFdDyKjCmUhKSIZLWR4BhJ?= =?us-ascii?q?detC0bK+nBN3fGKuX3ZTcxBsVIWQwt1Xi6NU9IBJS2PAWK8TXhpQIVT1/0PA9x?= =?us-ascii?q?Y+D0AZL6jsKt1un09YeZK1FDjT+5JLdzNwmerAPLt8BQj5E0eYgrzR6ci31EYe?= =?us-ascii?q?lUjUlhOF+J10L14Muq8Zwl+S1NtugJ/shMS6j4Oa8/SOoLX3wdL2kp6Ziz5lH4?= =?us-ascii?q?RgyV6y5EXw=3D=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0C0AgCMKB1ahrWhVdFcHQEBBQELAYQib?= =?us-ascii?q?icHg3iZNI98iiEDXAobihcHQxQBAQEBAQEBAQEBEgEBAQgLCwgoJAuCOCKCbwQ?= =?us-ascii?q?ZAQE4JQ8CJgIkEgEFASKKNZsbQIsiboFtOoMJAQEFiBYIEn2CK4IHgVWBaYZDh?= =?us-ascii?q?RmCY4o/mA+BdkGFO40agnmQVpYrFAUfgRY2gXIyGiOBAAaBcQmCOg8QDIFodgG?= =?us-ascii?q?JBwGBEwEBAQ?= X-IPAS-Result: =?us-ascii?q?A0C0AgCMKB1ahrWhVdFcHQEBBQELAYQibicHg3iZNI98iiE?= =?us-ascii?q?DXAobihcHQxQBAQEBAQEBAQEBEgEBAQgLCwgoJAuCOCKCbwQZAQE4JQ8CJgIkE?= =?us-ascii?q?gEFASKKNZsbQIsiboFtOoMJAQEFiBYIEn2CK4IHgVWBaYZDhRmCY4o/mA+BdkG?= =?us-ascii?q?FO40agnmQVpYrFAUfgRY2gXIyGiOBAAaBcQmCOg8QDIFodgGJBwGBEwEBAQ?= X-IronPort-AV: E=Sophos;i="5.44,467,1505772000"; d="scan'208";a="246316532" Received: from mail-yw0-f181.google.com ([209.85.161.181]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/AES128-GCM-SHA256; 28 Nov 2017 10:16:45 +0100 Received: by mail-yw0-f181.google.com with SMTP id g193so2744583ywe.3 for ; Tue, 28 Nov 2017 01:16:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=andrej-com.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=yuC4e3omVPp/bkpCFBelHL2eYALvWXe2okodu1uQ5Fc=; b=sLSpdrJEyOOV6J7Htd1emUGX6ahqiT54QVtZIassJ/mVRdyl6o4TCGrQy/RZstmbuE lnHMhdkgkPNUUyR3QQvPeRDglIqAOki2mJeGtcXbr2/njNjsMgyLLYpPwHd48BmGtbrU yavvOD0elS2216RlLLtbHYm3lLu8nP16CF9m7j9EBi8HeuHzt+dZlhqiUeyaxWwmCN1t 2WI+KoHY0E0PqO+apfa9qHFlcCQgAD7hwFRyPGKOPIXbbhOSwtaYhi8RidPS9cGNPXMR faxFox53w3JaygO/xs1lrVc/fli4fpIVwBXe9sOctPDUFn8jXC+QLnjoujWec3SJAU1f eufQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=yuC4e3omVPp/bkpCFBelHL2eYALvWXe2okodu1uQ5Fc=; b=mTiQiNPZwdiNpbchL6GQ6GtQJ5B/PCd1qPmQhqW30PdzEKO7AG+XW1xp5X5ONm4n2L sM1EVo7bTKwbjcioGZtTI5iJFSq+3T1+ixhiRWMIpROPn2VStI9synvy+Cq35EX+N1bq v4LQQm+baJVTty9kxLur6NEtAlNnJpKaY3CVPGRofvHvOsi+EYpo8wqXet630cutHutw ITaZkQEP1qOxyXHyXvPnu87jRmjun+Ytaqjo6HPxTFaTpliC8XwN7iFy+bWXocHpoeFE YWfRtIMDAtpk1M90/D5tEK3brqZypHXAZQnlUc9y4MsnX54zSnJ2MKYZGuMCoBqv59bz rC2w== X-Gm-Message-State: AJaThX48v7JseJmCNQY1Eml5QFIvf7okTwHQGcwNrpKZOViYsg6qo8Ce WIiw/coRyRIoOqBUIty6Fb2m7rXK+ZMlREi7e2JQYRCd X-Google-Smtp-Source: AGs4zMaT8HKrt9G6KnKh9BtIbwI3uWYCs0WXyORJg/fE1LEgi2nuAqwrahlKGVjwIunVZaWGykscVBR/8HXMxWwMuL8= X-Received: by 10.129.42.87 with SMTP id q84mr27622266ywq.482.1511860604209; Tue, 28 Nov 2017 01:16:44 -0800 (PST) MIME-Version: 1.0 Received: by 10.37.33.2 with HTTP; Tue, 28 Nov 2017 01:16:43 -0800 (PST) X-Originating-IP: [192.76.146.22] From: Andrej Bauer Date: Tue, 28 Nov 2017 10:16:43 +0100 Message-ID: To: "caml-list@inria.fr" Content-Type: text/plain; charset="UTF-8" Subject: [Caml-list] Problem with Mpfr rounding modes (FFI interface) I seem to be hitting some sort of a bug in the interface between OCaml and the MPFR library for multiple-precision floating point. I am on macOS 10.13.1, Ocaml 4.04.1 (but also 4.02.1 behaves the same way), OPAM package mlgmpidl 1.2.4. MPFR was installed via Homebrew and it is version 3.1. The following complete program shows that rounding modes do not work correctly. Let me describe the problem. -----------test_rounding.ml---------------- (* Testing rounding modes in Mpfr. *) (* Requires OPAM package mlgmpidl *) (* Compile with: ocamlbuild -use-ocamlfind -pkg gmp test_rounding.native *) let test_modes prec x = (* Create MFPR variables with the given precision, one per rounding mode. *) let a_Near : Mpfr.t = Mpfr.init2 prec and a_Zero : Mpfr.t = Mpfr.init2 prec and a_Up : Mpfr.t = Mpfr.init2 prec and a_Down : Mpfr.t = Mpfr.init2 prec and a_Away : Mpfr.t = Mpfr.init2 prec and a_Faith : Mpfr.t = Mpfr.init2 prec and a_NearAway : Mpfr.t = Mpfr.init2 prec in (* Set the variables with various rounding modes *) ignore (Mpfr.set_d a_Near x Mpfr.Near) ; ignore (Mpfr.set_d a_Zero x Mpfr.Zero) ; ignore (Mpfr.set_d a_Up x Mpfr.Up) ; ignore (Mpfr.set_d a_Down x Mpfr.Down) ; ignore (Mpfr.set_d a_Away x Mpfr.Away) ; ignore (Mpfr.set_d a_Faith x Mpfr.Faith) ; ignore (Mpfr.set_d a_NearAway x Mpfr.NearAway) ; (* Print the results *) Format.printf "x = %F@." x ; Format.printf "a_Near = %t@." (fun ppf -> Mpfr.print ppf a_Near) ; Format.printf "a_Zero = %t@." (fun ppf -> Mpfr.print ppf a_Zero) ; Format.printf "a_Up = %t@." (fun ppf -> Mpfr.print ppf a_Up) ; Format.printf "a_Down = %t@." (fun ppf -> Mpfr.print ppf a_Down) ; Format.printf "a_Away = %t@." (fun ppf -> Mpfr.print ppf a_Away) ; Format.printf "a_Faith = %t@." (fun ppf -> Mpfr.print ppf a_Faith) ; Format.printf "a_NearAway = %t@." (fun ppf -> Mpfr.print ppf a_NearAway) ;; test_modes 11 1024.3333333333333 ;; ------------------------------------------------- The output is: x = 1024.33333333 a_Near = 0.10240E4 a_Zero = 0.10240E4 a_Up = 0.10240E4 a_Down = 0.10240E4 a_Away = 0.10250E4 a_Faith = 0.10250E4 a_NearAway = 0.10250E4 The problem is that a_Up is smaller than x, and that it is equal to a_Down. In fact, the rounding modes behave in strange ways (try plugging in other values of x). The problem persists if I try to convert from string, or copy one Mpfr float into another, etc. I am not familiar with the FFI interface, but I can tell you where the rounding modes are defined. In the mlgmpidl library there is in mpfr.ml the type round, defined as type round = | Near | Zero | Up | Down | Away | Faith | NearAway The corresponding enum type in the C library is defined in /usr/local/include/mpfr.h, defined as typedef enum { MPFR_RNDN=0, /* round to nearest, with ties to even */ MPFR_RNDZ, /* round toward zero */ MPFR_RNDU, /* round toward +Inf */ MPFR_RNDD, /* round toward -Inf */ MPFR_RNDA, /* round away from zero */ MPFR_RNDF, /* faithful rounding (not implemented yet) */ MPFR_RNDNA=-1 /* round to nearest, with ties away from zero (mpfr_round) */ } mpfr_rnd_t; Conversion from the OCaml round to the C mpfr_rnd_t is in mlgmpidl library in gmp_caml.h and it looks like this: static inline void camlidl_mpfr_rnd_t_ml2c(value val, mpfr_rnd_t* rnd) { int arg = Int_val(val); #if MPFR_VERSION_MAJOR >= 3 arg = (arg==6) ? (int)MPFR_RNDNA : arg; #endif *rnd = (mpfr_rnd_t)arg; } So, it's using Int_val to convert the OCalml tag to the enum value. Is this the way to do it? Has there been a change in recent OCaml versions? Or am I just doing something else wrong? Any help is appreciated. With kind regards, Andrej