comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: getting same output as gfortran, long_float
Date: Fri, 1 May 2015 00:08:36 +0200
Date: 2015-05-01T00:08:36+02:00	[thread overview]
Message-ID: <1kxou0nloqg9c$.1x0itzgdrlosm$.dlg@40tude.net> (raw)
In-Reply-To: mhu65r$ntj$1@speranza.aioe.org

On Thu, 30 Apr 2015 16:17:49 -0500, Nasser M. Abbasi wrote:

> I am learning Ada again, and was wondering what do I need to change
> in this small code to make it output the same precision as gfortran?
> 
> First I show the code, then explain more what the issue.
> 
> Fortran:
> 
> --------------------
> PROGRAM foo
> IMPLICIT NONE
> INTEGER, PARAMETER :: DBL = KIND(1.D0)
> REAL(KIND = DBL) :: x
>    x = 12.0D0 * 0.0001D0/(1.0D0 * (1.0D0 - 0.1D0)**4 )
> PRINT *, x
> END PROGRAM
> -------------------
> 
> Now, gfortran has an option called -fdefault-real-8 which I thought
> will map to Ada long_float.
> 
> https://gcc.gnu.org/onlinedocs/gfortran/Fortran-Dialect-Options.html
> "-fdefault-real-8 Set the default real type to an 8 byte wide type."
> 
> When compiling and running the above Fortran program, this is the output
> 
> -------------------
> gfortran -Wall -fdefault-real-8  foo2.f90
> ./a.out
>     1.82898948331047096479195244627343369E-0003
> 
> gfortran -Wall  foo2.f90
> ./a.out
>     1.8289894833104711E-003
> ----------------------------------------
> 
> It is the first result above I'd like to get with Ada. Here is
> what I tried:
> 
> --------------------
> with ada.text_io; use ada.text_io;
> procedure foo_2 is
>    x : Long_Float;
> begin
>    x := 12.0 * 0.0001/(1.0 * (1.0 - 0.1)**4 );
>    put_line(long_float'image(x));
> end foo_2;
> ----------------------
> 
> compile and run:
> 
> gnatmake foo_2.adb
> gcc-4.8 -c foo_2.adb
> gnatbind -x foo_2.ali
> gnatlink foo_2.ali
> ./foo_2
>   1.82898948331047E-03
> 
> 
> side-by-side:
> =============
> Ada (long)                1.82898948331047E-03
> Ada (long long)           1.82898948331047096E-03
> Fortran:                  1.8289894833104711E-003
> Fortran -fdefault-real-8: 1.82898948331047096479195244627343369E-0003
> 
> How to obtain the last result above in Ada?
>
> ps. here is the long_long_float Ada version.
> 
> -------------
> with ada.text_io; use ada.text_io;
> procedure foo_2 is
>    x : Long_Long_Float;
> begin
>    x := 12.0 * 0.0001/(1.0 * (1.0 - 0.1)**4 );
>    put_line(Long_Long_Float'image(x));
> end foo_2;
> ----------------

I don't know what FORTRAN does, but assuming, you are using Intel, the
longest floating-point available there is not, as you seem assume, of 16
bytes (quadruple-precision), but so-called extended precision, which is not
that long (10 bytes, namely). 

AFAIK, GNAT on x86 maps:

Float to single precision float (4 bytes)
Long_Float to double precision float (8 bytes)
Long_Long_Float to extended precision float (10 bytes, effectively)

You can try this program to see how many binary mantissa bits are available
for each type:
-----------------------------
with Text_IO; use Text_IO;
procedure Test is
begin
   Put_Line ("Float mantissa:" & Integer'Image (Float'Machine_Mantissa));
   Put_Line ("Long Float mantissa:" & Integer'Image
(Long_Float'Machine_Mantissa));
   Put_Line ("Long Long Float mantissa:" & Integer'Image
(Long_Long_Float'Machine_Mantissa));
end Test;
--------------------------
On an Intel machine it will print:

Float mantissa: 24
Long_Float mantissa: 53
Long_Long_Float mantissa: 64

If FORTRAN supports longer floating point numbers (e.g.
quadruple-precision) then it must emulate them since Intel hardware does
not have them. That would make computations quite slow and you should
consider if you really need that many significant digits.

If GNAT allowed floating-point emulation, you could declare a custom type
of required precision:

   type My_Float is digits 34; -- 112 * lg(2)

Which is advisable anyway in order to make your program portable. Using
built-in types is a bad idea and poor taste in most cases.

Since GNAT does support emulation, at least not with the standard compiler
switches, you need a library for doing this.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

  reply	other threads:[~2015-04-30 22:08 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-30 21:17 getting same output as gfortran, long_float Nasser M. Abbasi
2015-04-30 22:08 ` Dmitry A. Kazakov [this message]
2015-04-30 22:11   ` Dmitry A. Kazakov
2015-04-30 22:37   ` Nasser M. Abbasi
2015-04-30 22:53     ` Nasser M. Abbasi
2015-05-01  7:22       ` Jacob Sparre Andersen
2015-05-01  1:12   ` Nasser M. Abbasi
2015-05-01  6:52     ` Dmitry A. Kazakov
2015-05-01  7:32       ` Nasser M. Abbasi
2015-05-01  7:45         ` Dmitry A. Kazakov
2015-05-04  0:15           ` robin.vowels
2015-05-04  7:21             ` Dmitry A. Kazakov
2015-05-04  8:53               ` robin.vowels
2015-05-04 10:18                 ` Dmitry A. Kazakov
2015-05-04 13:45                   ` robin.vowels
2015-05-04 14:47                     ` Dmitry A. Kazakov
2015-05-07  2:01                       ` robin.vowels
2015-05-01 23:24       ` Dennis Lee Bieber
2015-05-04  0:09       ` robin.vowels
2015-05-01  7:01     ` Dmitry A. Kazakov
2015-05-04  0:42     ` robin.vowels
2015-04-30 22:12 ` Jeffrey R. Carter
2015-04-30 22:27   ` Qun-Ying
2015-05-01  0:59     ` Dennis Lee Bieber
2015-04-30 22:32   ` Nasser M. Abbasi
2015-05-01  1:16     ` Jeffrey R. Carter
2015-05-01  1:40       ` Nasser M. Abbasi
2015-05-01  7:47         ` Jacob Sparre Andersen
2015-05-01 15:39         ` Waldek Hebisch
2015-05-01 17:27           ` Nasser M. Abbasi
2015-05-01 18:03             ` Nasser M. Abbasi
2015-05-04  0:51             ` robin.vowels
2015-05-04  0:47         ` robin.vowels
2015-05-01  8:21 ` Simon Wright
2015-05-01 11:55 ` Georg Bauhaus
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox