Chip noticed that the intended optionality of the 'IV' was
[p5sagit/p5-mst-13.2.git] / hints / t001.c
CommitLineData
c50b6f56 1/* Beginning of modification history */
2/* Written 02-04-10 by Paul Green (Paul.Green@stratus.com) */
3/* End of modification history */
4
5/* This test case is extracted from Perl version 5.7.3. It is
6 in the Perl_unpack_str function of the pp_pack.c source file.
7
8 GCC 2.95.2 improperly assumes that it can compensate for an
9 extra fsub by performing a fadd. This would work in
10 fixed-point arithmetic, but does not work in floating-point
11 arithmetic.
12
13 This problem has been seen on HP-UX and on Stratus VOS, both
14 of which have an HP PA-RISC target (hppa1.1). The Stratus
15 bug number is gnu_g++-220. */
16
17/* #define _POSIX_C_SOURCE 199506L -- added by Configure */
18#include <stdio.h>
19#include <string.h>
20#include <math.h>
21
22void test(double *result)
23{
24 float afloat;
25 double adouble;
26 int checksum = 0;
27 unsigned cuv = 0;
28 double cdouble = 0.0;
29 const int bits_in_uv = 8 * sizeof(cuv);
30
31 checksum = 53;
32 cdouble = -1.0;
33
34 if (checksum) {
35 if (checksum > bits_in_uv) {
36 double trouble;
37
38 adouble = (double) (1 << (checksum & 15));
39
40 while (checksum >= 16) {
41 checksum -= 16;
42 adouble *= 65536.0;
43 }
44
45 /* At -O1, GCC 2.95.2 compiles the following loop
46 into:
47
48 L$0014
49 fcmp,dbl,>= %fr4,%fr0
50 ftest
51 b L$0014
52 fadd,dbl %fr4,%fr12,%fr4
53 fsub,dbl %fr4,%fr12,%fr4
54
55 This code depends on the floading-add and
56 floating-subtract retaining all of the
57 precision present in the operands. There is
58 no such guarantee when using floating-point,
59 as this test case demonstrates.
60
61 The code is okay at -O0. */
62
63 while (cdouble < 0.0)
64 cdouble += adouble;
65
66 cdouble = modf (cdouble / adouble, &trouble) * adouble;
67 }
68 }
69
70 *result = cdouble;
71}
72
73int main (int argc, char ** argv)
74{
75double value;
76
77 test (&value);
78
79 if (argc == 2 && !strcmp(argv[1],"-v"))
80 printf ("value = %.18e\n", value);
81
82 if (value != 9.007199254740991e+15) {
83 printf ("t001 fails!\n");
84 return -1;
85 }
86 else {
87 printf ("t001 works.\n");
88 return 0;
89 }
90}