Update spec to require automake >= 1.13
[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 #ifdef HAVE_UINTMAX_T
30
31 /* Assume IEEE-754 arithmetic on pre-C89 hosts.  */
32 #ifndef FLT_RADIX
33 #define FLT_RADIX 2
34 #endif
35 #ifndef FLT_MANT_DIG
36 #define FLT_MANT_DIG 24
37 #endif
38 #ifndef DBL_MANT_DIG
39 #define DBL_MANT_DIG 53
40 #endif
41
42 /*
43  * The number of base-FLT_RADIX digits in an AWKNUM fraction, assuming
44  * that AWKNUM is not long double.
45  */
46 #define AWKSMALL_MANT_DIG \
47   (sizeof (AWKNUM) == sizeof (double) ? DBL_MANT_DIG : FLT_MANT_DIG)
48
49 /*
50  * The number of base-FLT_DIGIT digits in an AWKNUM fraction, even if
51  * AWKNUM is long double.  Don't mention 'long double' unless
52  * LDBL_MANT_DIG is defined, for the sake of ancient compilers that
53  * lack 'long double'.
54  */
55 #ifdef LDBL_MANT_DIG
56 #define AWKNUM_MANT_DIG \
57   (sizeof (AWKNUM) == sizeof (long double) ? LDBL_MANT_DIG : AWKSMALL_MANT_DIG)
58 #else
59 #define AWKNUM_MANT_DIG AWKSMALL_MANT_DIG
60 #endif
61
62 /*
63  * The number of bits in an AWKNUM fraction, assuming FLT_RADIX is
64  * either 2 or 16.  IEEE and VAX formats use radix 2, and IBM
65  * mainframe format uses radix 16; we know of no other radices in
66  * practical use.
67  */
68 #if FLT_RADIX != 2 && FLT_RADIX != 16
69 Please port the following code to your weird host;
70 #endif
71 #define AWKNUM_FRACTION_BITS (AWKNUM_MANT_DIG * (FLT_RADIX == 2 ? 1 : 4))
72 #define DBL_FRACTION_BITS (DBL_MANT_DIG * (FLT_RADIX == 2 ? 1 : 4))
73
74 /* adjust_uint --- fiddle with values, ask Paul Eggert to explain */
75
76 uintmax_t
77 adjust_uint(uintmax_t n)
78 {
79         /*
80          * If uintmax_t is so wide that AWKNUM cannot represent all its
81          * values, strip leading nonzero bits of integers that are so large
82          * that they cannot be represented exactly as AWKNUMs, so that their
83          * low order bits are represented exactly, without rounding errors.
84          * This is more desirable in practice, since it means the user sees
85          * integers that are the same width as the AWKNUM fractions.
86          */
87         if (AWKNUM_FRACTION_BITS < CHAR_BIT * sizeof n)
88                 n &= ((uintmax_t) 1 << AWKNUM_FRACTION_BITS) - 1;
89
90         return n;
91 }
92 #endif /* HAVE_UINTMAX_T */