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