Introduced -devel and -extras subpackages for gawk
[platform/upstream/gawk.git] / floatcomp.c
1 /*
2  * floatcomp.c - Isolate floating point details.
3  */
4
5 /* 
6  * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
7  * 
8  * This file is part of GAWK, the GNU implementation of the
9  * AWK Programming Language.
10  * 
11  * GAWK is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 3 of the License, or
14  * (at your option) any later version.
15  * 
16  * GAWK is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
24  */
25
26 #include "awk.h"
27 #include <math.h>
28
29 /* Assume IEEE-754 arithmetic on pre-C89 hosts.  */
30 #ifndef FLT_RADIX
31 #define FLT_RADIX 2
32 #endif
33 #ifndef FLT_MANT_DIG
34 #define FLT_MANT_DIG 24
35 #endif
36 #ifndef DBL_MANT_DIG
37 #define DBL_MANT_DIG 53
38 #endif
39
40 /*
41  * The number of base-FLT_RADIX digits in an AWKNUM fraction, assuming
42  * that AWKNUM is not long double.
43  */
44 #define AWKSMALL_MANT_DIG \
45   (sizeof (AWKNUM) == sizeof (double) ? DBL_MANT_DIG : FLT_MANT_DIG)
46
47 /*
48  * The number of base-FLT_DIGIT digits in an AWKNUM fraction, even if
49  * AWKNUM is long double.  Don't mention 'long double' unless
50  * LDBL_MANT_DIG is defined, for the sake of ancient compilers that
51  * lack 'long double'.
52  */
53 #ifdef LDBL_MANT_DIG
54 #define AWKNUM_MANT_DIG \
55   (sizeof (AWKNUM) == sizeof (long double) ? LDBL_MANT_DIG : AWKSMALL_MANT_DIG)
56 #else
57 #define AWKNUM_MANT_DIG AWKSMALL_MANT_DIG
58 #endif
59
60 /*
61  * The number of bits in an AWKNUM fraction, assuming FLT_RADIX is
62  * either 2 or 16.  IEEE and VAX formats use radix 2, and IBM
63  * mainframe format uses radix 16; we know of no other radices in
64  * practical use.
65  */
66 #if FLT_RADIX != 2 && FLT_RADIX != 16
67 Please port the following code to your weird host;
68 #endif
69 #define AWKNUM_FRACTION_BITS (AWKNUM_MANT_DIG * (FLT_RADIX == 2 ? 1 : 4))
70 #define DBL_FRACTION_BITS (DBL_MANT_DIG * (FLT_RADIX == 2 ? 1 : 4))
71
72 /*
73  * Floor and Ceil --- Work around a problem in conversion of
74  * doubles to exact integers.
75  */
76
77 /* Floor --- do floor(), also for Cray */
78
79 AWKNUM
80 Floor(AWKNUM n)
81 {
82         return floor(n);
83 }
84
85 /* Ceil --- do ceil(), also for Cray */
86
87 AWKNUM
88 Ceil(AWKNUM n)
89 {
90         return ceil(n);
91 }
92
93 #ifdef HAVE_UINTMAX_T
94 /* adjust_uint --- fiddle with values, ask Paul Eggert to explain */
95
96 uintmax_t
97 adjust_uint(uintmax_t n)
98 {
99         /*
100          * If uintmax_t is so wide that AWKNUM cannot represent all its
101          * values, strip leading nonzero bits of integers that are so large
102          * that they cannot be represented exactly as AWKNUMs, so that their
103          * low order bits are represented exactly, without rounding errors.
104          * This is more desirable in practice, since it means the user sees
105          * integers that are the same width as the AWKNUM fractions.
106          */
107         if (AWKNUM_FRACTION_BITS < CHAR_BIT * sizeof n)
108                 n &= ((uintmax_t) 1 << AWKNUM_FRACTION_BITS) - 1;
109
110         return n;
111 }
112 #endif /* HAVE_UINTMAX_T */