]> www.ginac.de Git - cln.git/blob - m4/floatparam.m4
Assume types 'long long int' and 'long double' exist.
[cln.git] / m4 / floatparam.m4
1 # floatparam.m4 serial 3  -*- Autoconf -*-
2 dnl Copyright (C) 2005-2008, 2017 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
6
7 dnl From Bruno Haible, Sam Steingold.
8
9 AC_DEFUN([CL_FLOATPARAM_CROSS],
10 [
11   cl_machine_file_h=$1
12   {
13     echo "/* Rounding modes, for use below */"
14     echo "#define rounds_to_nearest        0  /* 0.5 ulp */"
15     echo "#define rounds_to_zero           1  /* 1 ulp */"
16     echo "#define rounds_to_infinity       2  /* 1 ulp */"
17     echo "#define rounds_to_minus_infinity 3  /* 1 ulp */"
18     echo
19     for type in float double "long double"; do
20       if test -n "$type"; then
21         epsilon_bits=-1; y="($type)1.0"
22         while true; do
23           AC_COMPILE_IFELSE(
24             [AC_LANG_PROGRAM([],
25                [[typedef int verify[2*(
26                   (($type)(($type)1.0 + ($type)($y)) == ($type)1.0)
27                   || ($type)(($type)(($type)1.0 + ($type)($y)) - ($type)1.0) != ($type)($y)
28                  ) - 1];]])
29             ],
30             [break;])
31           epsilon_bits=`expr $epsilon_bits + 1`; y="$y * ($type)0.5"
32         done
33         negepsilon_bits=-1; y="($type)-1.0"
34         while true; do
35           AC_COMPILE_IFELSE(
36             [AC_LANG_PROGRAM([],
37                [[typedef int verify[2*(
38                   (($type)(($type)1.0 + ($type)($y)) == ($type)1.0)
39                   || ($type)(($type)(($type)1.0 + ($type)($y)) - ($type)1.0) != ($type)($y)
40                  ) - 1];]])
41             ],
42             [break;])
43           negepsilon_bits=`expr $negepsilon_bits + 1`; y="$y * ($type)0.5"
44         done
45         echo "/* Properties of type \`$type': */"
46         echo "/* Largest n for which 1+2^(-n) is exactly represented is $epsilon_bits. */"
47         echo "/* Largest n for which 1-2^(-n) is exactly represented is $negepsilon_bits. */"
48         if test `expr $negepsilon_bits '<=' $epsilon_bits` = 1; then
49           echo "#error \"No exponent jump at 1.0 for type $type!\""
50         else
51           if test `expr $negepsilon_bits '>' $epsilon_bits + 1` = 1; then
52             echo "/* Base for type '$type' is 2^"`expr $negepsilon_bits - $epsilon_bits`
53           fi
54           echo "#define "`echo $type | sed -e 's, ,_,g'`"_mant_bits "`expr $epsilon_bits + 1`
55         fi
56         x="($type)1.0"
57         i=$epsilon_bits
58         while test $i != 0; do
59           x="$x * ($type)0.5"
60           i=`expr $i - 1`
61         done
62         x="($type)($x)"
63         y1="($type)(($type)1.0 + ($type)5.0*$x)"
64         y2="($type)(($type)1.0 + ($type)6.0*$x)"
65         ys1="($type)(($type)1.0 + ($type)5.4*$x)"
66         ys2="($type)(($type)1.0 + ($type)5.6*$x)"
67         z1="($type)(($type)-1.0 + ($type)(-5.0)*$x)"
68         z2="($type)(($type)-1.0 + ($type)(-6.0)*$x)"
69         zs1="($type)(($type)-1.0 + ($type)(-5.4)*$x)"
70         zs2="($type)(($type)-1.0 + ($type)(-5.6)*$x)"
71         rounds=
72         if test -z "$rounds"; then
73           AC_COMPILE_IFELSE(
74             [AC_LANG_PROGRAM([],
75                [[typedef int verify[2*(
76                   $ys1 == $y1 && $ys2 == $y2 && $zs1 == $z1 && $zs2 == $z2
77                  ) - 1];]])
78             ],
79             [rounds=rounds_to_nearest])
80         fi
81         if test -z "$rounds"; then
82           AC_COMPILE_IFELSE(
83             [AC_LANG_PROGRAM([],
84                [[typedef int verify[2*(
85                   $ys1 == $y1 && $ys2 == $y1 && $zs1 == $z1 && $zs2 == $z1
86                  ) - 1];]])
87             ],
88             [rounds=rounds_to_zero])
89         fi
90         if test -z "$rounds"; then
91           AC_COMPILE_IFELSE(
92             [AC_LANG_PROGRAM([],
93                [[typedef int verify[2*(
94                   $ys1 == $y2 && $ys2 == $y2 && $zs1 == $z1 && $zs2 == $z1
95                  ) - 1];]])
96             ],
97             [rounds=rounds_to_infinity])
98         fi
99         if test -z "$rounds"; then
100           AC_COMPILE_IFELSE(
101             [AC_LANG_PROGRAM([],
102                [[typedef int verify[2*(
103                   $ys1 == $y1 && $ys2 == $y1 && $zs1 == $z2 && $zs2 == $z2
104                  ) - 1];]])
105             ],
106             [rounds=rounds_to_minus_infinity])
107         fi
108         if test -n "$rounds"; then
109           echo "#define "`echo $type | sed -e 's, ,_,g'`"_rounds $rounds"
110         else
111           echo "#error \"Unknown rounding mode for type $type!\""
112         fi
113         echo
114       fi
115     done
116     dnl Words-in-a-double endianness test. Note that, assuming IEEE 754 format,
117     dnl 2.5479915693083957     = { 0x40 0x04 0x62 0x49 0x67 0x65 0x4E 0x64 } ..bIgeNd
118     dnl 1.4396527506122064e164 = { 0x62 0x04 0x00 0x00 0x4E 0x65 0x67 0x49 } b...NegI
119     dnl 2.5495230282078065     = { 0x40 0x04 0x65 0x6C 0x54 0x54 0x69 0x4C } ..elTTiL
120     dnl 1.4139248369879473e214 = { 0x6C 0x65 0x00 0x00 0x4C 0x69 0x54 0x54 } le..LiTT
121     double_wordorder_bigendian_p=
122     AC_COMPILE_IFELSE(
123       [AC_LANG_PROGRAM([[
124          double a[9] = {
125            0, 2.5479915693083957, 0, 1.4396527506122064e164,
126            0, 2.5495230282078065, 0, 1.4139248369879473e214,
127            0 };
128          ]],
129          [])
130       ],
131       [if grep LiTTle conftest.$ac_objext >/dev/null; then
132          double_wordorder_bigendian_p=0
133        else
134          if grep bIgeN conftest.$ac_objext >/dev/null; then
135            double_wordorder_bigendian_p=1
136          fi
137        fi
138       ])
139     if test -n "$double_wordorder_bigendian_p"; then
140       echo "#define double_wordorder_bigendian_p $double_wordorder_bigendian_p"
141     else
142       echo "/* Dazed and confused!  Better not define anything. */"
143     fi
144     echo
145   } > "$cl_machine_file_h"
146 ])