public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Ada] Avoid the use of floating point in the front end
@ 2011-08-04 13:03 Arnaud Charlet
  0 siblings, 0 replies; only message in thread
From: Arnaud Charlet @ 2011-08-04 13:03 UTC (permalink / raw)
  To: gcc-patches; +Cc: Geert Bosch

[-- Attachment #1: Type: text/plain, Size: 604 bytes --]

There was one use of floating point in the front end, in a function
to estimate the equivalent decimal exponent for a universal real.
While this use was probably OK, because a different estimate
shouldn't affect compilation results, in general we do not want
anything in the compiler that may produce different results
depending on the host system.

The easiest way to achieve that goal is avoiding floating point
arithmetic.

Tested on x86_64-pc-linux-gnu, committed on trunk

2011-08-04  Geert Bosch  <bosch@adacore.com>

	* urealp.adb (Equivalent_Decimal_Exponent): Avoid the use of floating
	point.


[-- Attachment #2: difs --]
[-- Type: text/plain, Size: 4508 bytes --]

Index: urealp.adb
===================================================================
--- urealp.adb	(revision 177274)
+++ urealp.adb	(working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -128,7 +128,7 @@
    --  U is a Ureal entry for which the base value is non-zero, the value
    --  returned is the equivalent decimal exponent value, i.e. the value of
    --  Den, adjusted as though the base were base 10. The value is rounded
-   --  to the nearest integer, and so can be one off.
+   --  toward zero (truncated), and so its value can be off by one.
 
    function Is_Integer (Num, Den : Uint) return Boolean;
    --  Return true if the real quotient of Num / Den is an integer value
@@ -244,29 +244,48 @@
 
    function Equivalent_Decimal_Exponent (U : Ureal_Entry) return Int is
 
-      --  The following table is a table of logs to the base 10
+      type Ratio is record
+         Num : Nat;
+         Den : Nat;
+      end record;
 
-      Logs : constant array (Nat range 1 .. 16) of Long_Float := (
-                1 => 0.000000000000000,
-                2 => 0.301029995663981,
-                3 => 0.477121254719662,
-                4 => 0.602059991327962,
-                5 => 0.698970004336019,
-                6 => 0.778151250383644,
-                7 => 0.845098040014257,
-                8 => 0.903089986991944,
-                9 => 0.954242509439325,
-               10 => 1.000000000000000,
-               11 => 1.041392685158230,
-               12 => 1.079181246047620,
-               13 => 1.113943352306840,
-               14 => 1.146128035678240,
-               15 => 1.176091259055680,
-               16 => 1.204119982655920);
+      --  The following table is a table of logs to the base 10. All values
+      --  have at least 15 digits of precision, and do not exceed the true
+      --  value. To avoid the use of floating point, and as a result potential
+      --  target dependency, each entry is represented as a fraction of two
+      --  integers.
 
+      Logs : constant array (Nat range 1 .. 16) of Ratio :=
+        (1 => (Num =>           0, Den =>            1),  -- 0
+         2 => (Num =>  15_392_313, Den =>   51_132_157),  -- 0.301029995663981
+         3 => (Num => 731_111_920, Den => 1532_339_867),  -- 0.477121254719662
+         4 => (Num =>  30_784_626, Den =>   51_132_157),  -- 0.602059991327962
+         5 => (Num => 111_488_153, Den =>  159_503_487),  -- 0.698970004336018
+         6 => (Num =>  84_253_929, Den =>  108_274_489),  -- 0.778151250383643
+         7 => (Num =>  35_275_468, Den =>   41_741_273),  -- 0.845098040014256
+         8 => (Num =>  46_176_939, Den =>   51_132_157),  -- 0.903089986991943
+         9 => (Num => 417_620_173, Den =>  437_645_744),  -- 0.954242509439324
+        10 => (Num =>           1, Den =>            1),  -- 1.000000000000000
+        11 => (Num => 136_507_510, Den =>  131_081_687),  -- 1.041392685158225
+        12 => (Num =>  26_797_783, Den =>   24_831_587),  -- 1.079181246047624
+        13 => (Num =>  73_333_297, Den =>   65_832_160),  -- 1.113943352306836
+        14 => (Num => 102_941_258, Den =>   89_816_543),  -- 1.146128035678238
+        15 => (Num =>  53_385_559, Den =>   45_392_361),  -- 1.176091259055681
+        16 => (Num =>  78_897_839, Den =>   65_523_237)); -- 1.204119982655924
+
+      function Scale (X : Int; R : Ratio) return Int;
+      --  Compute the value of X scaled by R
+
+      function Scale (X : Int; R : Ratio) return Int is
+         type Wide_Int is range -2**63 .. 2**63 - 1;
+
+      begin
+         return Int (Wide_Int (X) * Wide_Int (R.Num) / Wide_Int (R.Den));
+      end Scale;
+
    begin
       pragma Assert (U.Rbase /= 0);
-      return Int (Long_Float (UI_To_Int (U.Den)) * Logs (U.Rbase));
+      return Scale (UI_To_Int (U.Den), Logs (U.Rbase));
    end Equivalent_Decimal_Exponent;
 
    ----------------

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-08-04 13:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-04 13:03 [Ada] Avoid the use of floating point in the front end Arnaud Charlet

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 read-only IMAP folder(s) and NNTP newsgroup(s).