From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: getting same output as gfortran, long_float Date: Fri, 1 May 2015 00:08:36 +0200 Organization: cbb software GmbH Message-ID: <1kxou0nloqg9c$.1x0itzgdrlosm$.dlg@40tude.net> References: Reply-To: mailbox@dmitry-kazakov.de NNTP-Posting-Host: evoS9sCOdnHjo0GRLLMU1Q.user.speranza.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: 40tude_Dialog/2.0.15.1 X-Notice: Filtered by postfilter v. 0.8.2 Xref: news.eternal-september.org comp.lang.ada:25666 Date: 2015-05-01T00:08:36+02:00 List-Id: 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