Default format for Float128

Jerry DeLisle jvdelisle@frontier.com
Thu Sep 2 07:57:00 GMT 2010


Hi all,

With FX help I managed to get a build working with the libquad support. 
(allowing me to test)

The following program illustrates some default formatting.

program test_quad
   real(16) :: num1, num2, num3
   real(8) :: tmp

   num1 = 23.456_16 / 3.3_16
   num2 = 42.86_16
   num3 = -5.2562-16
   tmp = num1 + num2 + num3
   print *, "1234567890123456789012345678901234567890"
   write(*,*) tmp
   write(*,*) num1
   write(*,*) num2
   write(*,*) num3
   write(*,*) num1 + num2 + num3
   print *, "1234567890123456789012345678901234567890"
   print *, 1.0_16/3.0_16
   print *, 1.0_10/3.0_10
   print *, 1.0_8/3.0_8
   print *, 1.0_4/3.0_4
end program test_quad

Which on my system, results in:

$ ./a.out
  1234567890123456789012345678901234567890
    28.711679904822148
    7.1078787878787878787879000000000000
    42.860000000000000000000000000000000
   -21.256198883056640625000000000000000
    28.711679904822147253788000000000000
  1234567890123456789012345678901234567890
   0.33333333333333333333333000000000000
   0.33333333333333333334
   0.33333333333333331
   0.33333334

There appears to be a lot of excess width here.  If I modify write.c with this:

Index: write.c
===================================================================
--- write.c     (revision 163712)
+++ write.c     (working copy)
@@ -1447,8 +1447,8 @@
        f->u.real.e = 4;
        break;
      case 16:
-      f->u.real.w = 44;
-      f->u.real.d = 35;
+      f->u.real.w = 32;
+      f->u.real.d = 23;
        f->u.real.e = 4;
        break;
      default:

The result is:

$ ./a.out
  1234567890123456789012345678901234567890
    28.711679904822148
    7.1078787878787878787879
    42.860000000000000000000
   -21.256198883056640625000
    28.711679904822147253788
  1234567890123456789012345678901234567890
   0.33333333333333333333333
   0.33333333333333333334
   0.33333333333333331
   0.33333334

This seems reasonable to me and it passes regression, but read further and PR24685.

Also note that with a real(10) specified as follows:

   print "(1x,1PG43.34E4)", 1.0_16/3.0_16
   print "(1x,1PG43.34E4)", 1.0_10/3.0_10

We get:

   0.3333333333333333333333300000000000
   0.3333333333333333333423700000000000

This makes some sense since we internally store kind 10 in 16 bytes and thus the 
garbage digits in the kind 10 result (Maybe thats a bug really).

Browsing the history we see the current default settings were bumped up by:

Modified Mon Apr 10 12:02:55 2006 UTC (4 years, 4 months ago) by jakub

	(write_real): Output REAL(16) as 1PG43.34E4 rather than 1PG40.31E4.

and again:

2008-01-18  Tobias Burnus  <burnus@net-b.de>

         * io/write.c (write_real): Increase default precision for
         * REAL(16) by one.

To summarize, the default width is set higher to accommodate ppc and IBM 
architectures.

The following test taken from comment #19 of pr24685 fails with the new quad 
float patch on x86-64. The values come out +Infinity on my system here.

program huge_real10_formatted
   integer, parameter :: k = 16
   real(kind=k) :: a,b(2), c
   character(len=180) :: tmp
   ! Test real(k) scalar and array formatted IO with big value
   b(:) = huge (1.0_k)/2
   print *, 'real(16) big value:      ', b(1)
   write (tmp, *) b
   read (tmp, *) a, c
   print *, 'same value read again:   ', a
   print *, 'difference: looks broken ', a-b(1)
   ! Test with really big value
   b(:) = huge (1.0_k)
   print *, 'huge value: ', b(1)
   write (tmp, *) b
   read (tmp, *) a, c
   print *, "tmp=", tmp
   print *, "Whats this about!!"
   print *, a
   print *, b(1)
   print *, b(2)
   print *, c
   !if (a /= b(1)) call abort ()
   !if (c /= b(2)) call abort ()
end program huge_real10_formatted

$ ./a.out
  real(16) big value:        5.94865747678615882542880000000000000E+4931
  same value read again:     5.94865747678615882542880000000000000E+4931
  difference: looks broken   3.36685996541765098451450000000000000E+4907
  huge value:                                     +Infinity
  tmp=                                    +Infinity 
        +Infinity 

  Whats this about!!
                                     +Infinity
                                     +Infinity
                                     +Infinity
                                     +Infinity

I will keep picking at this, but I think we need to leave the default widths 
alone. Then for platforms using libquad, consider reduced width.  Also see why 
Huge is coming out Infinity. ???

Regards,

Jerry



More information about the Fortran mailing list