maint: update copyright
[gnulib.git] / tests / test-printf-frexp.c
1 /* Test of splitting a double into fraction and mantissa.
2    Copyright (C) 2007-2014 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
18
19 #include <config.h>
20
21 #include "printf-frexp.h"
22
23 #include <float.h>
24
25 #include "macros.h"
26
27 static double
28 my_ldexp (double x, int d)
29 {
30   for (; d > 0; d--)
31     x *= 2.0;
32   for (; d < 0; d++)
33     x *= 0.5;
34   return x;
35 }
36
37 int
38 main ()
39 {
40   int i;
41   /* The use of 'volatile' guarantees that excess precision bits are dropped
42      when dealing with denormalized numbers.  It is necessary on x86 systems
43      where double-floats are not IEEE compliant by default, to avoid that the
44      results become platform and compiler option dependent.  'volatile' is a
45      portable alternative to gcc's -ffloat-store option.  */
46   volatile double x;
47
48   for (i = 1, x = 1.0; i <= DBL_MAX_EXP; i++, x *= 2.0)
49     {
50       int exp = -9999;
51       double mantissa = printf_frexp (x, &exp);
52       ASSERT (exp == i - 1);
53       ASSERT (mantissa == 1.0);
54     }
55   for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
56     {
57       int exp = -9999;
58       double mantissa = printf_frexp (x, &exp);
59       ASSERT (exp == i - 1);
60       ASSERT (mantissa == 1.0);
61     }
62   for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
63     {
64       int exp = -9999;
65       double mantissa = printf_frexp (x, &exp);
66       ASSERT (exp == DBL_MIN_EXP - 1);
67       ASSERT (mantissa == my_ldexp (1.0, i - DBL_MIN_EXP));
68     }
69
70   for (i = 1, x = 1.01; i <= DBL_MAX_EXP; i++, x *= 2.0)
71     {
72       int exp = -9999;
73       double mantissa = printf_frexp (x, &exp);
74       ASSERT (exp == i - 1);
75       ASSERT (mantissa == 1.01);
76     }
77   for (i = 1, x = 1.01; i >= DBL_MIN_EXP; i--, x *= 0.5)
78     {
79       int exp = -9999;
80       double mantissa = printf_frexp (x, &exp);
81       ASSERT (exp == i - 1);
82       ASSERT (mantissa == 1.01);
83     }
84   for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
85     {
86       int exp = -9999;
87       double mantissa = printf_frexp (x, &exp);
88       ASSERT (exp == DBL_MIN_EXP - 1);
89       ASSERT (mantissa >= my_ldexp (1.0, i - DBL_MIN_EXP));
90       ASSERT (mantissa <= my_ldexp (2.0, i - DBL_MIN_EXP));
91       ASSERT (mantissa == my_ldexp (x, - exp));
92     }
93
94   for (i = 1, x = 1.73205; i <= DBL_MAX_EXP; i++, x *= 2.0)
95     {
96       int exp = -9999;
97       double mantissa = printf_frexp (x, &exp);
98       ASSERT (exp == i - 1);
99       ASSERT (mantissa == 1.73205);
100     }
101   for (i = 1, x = 1.73205; i >= DBL_MIN_EXP; i--, x *= 0.5)
102     {
103       int exp = -9999;
104       double mantissa = printf_frexp (x, &exp);
105       ASSERT (exp == i - 1);
106       ASSERT (mantissa == 1.73205);
107     }
108   for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
109     {
110       int exp = -9999;
111       double mantissa = printf_frexp (x, &exp);
112       ASSERT (exp == DBL_MIN_EXP - 1);
113       ASSERT (mantissa >= my_ldexp (1.0, i - DBL_MIN_EXP));
114       ASSERT (mantissa <= my_ldexp (2.0, i - DBL_MIN_EXP));
115       ASSERT (mantissa == my_ldexp (x, - exp));
116     }
117
118   return 0;
119 }