File: floatparam.m4

package info (click to toggle)
cln 1.3.7-1
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,996 kB
  • sloc: cpp: 80,860; sh: 5,138; ansic: 3,174; makefile: 1,274
file content (146 lines) | stat: -rw-r--r-- 5,658 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# floatparam.m4 serial 3  -*- Autoconf -*-
dnl Copyright (C) 2005-2008, 2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

dnl From Bruno Haible, Sam Steingold.

AC_DEFUN([CL_FLOATPARAM_CROSS],
[
  cl_machine_file_h=$1
  {
    echo "/* Rounding modes, for use below */"
    echo "#define rounds_to_nearest        0  /* 0.5 ulp */"
    echo "#define rounds_to_zero           1  /* 1 ulp */"
    echo "#define rounds_to_infinity       2  /* 1 ulp */"
    echo "#define rounds_to_minus_infinity 3  /* 1 ulp */"
    echo
    for type in float double "long double"; do
      if test -n "$type"; then
        epsilon_bits=-1; y="($type)1.0"
        while true; do
          AC_COMPILE_IFELSE(
            [AC_LANG_PROGRAM([],
               [[typedef int verify[2*(
                  (($type)(($type)1.0 + ($type)($y)) == ($type)1.0)
                  || ($type)(($type)(($type)1.0 + ($type)($y)) - ($type)1.0) != ($type)($y)
                 ) - 1];]])
            ],
            [break;])
          epsilon_bits=`expr $epsilon_bits + 1`; y="$y * ($type)0.5"
        done
        negepsilon_bits=-1; y="($type)-1.0"
        while true; do
          AC_COMPILE_IFELSE(
            [AC_LANG_PROGRAM([],
               [[typedef int verify[2*(
                  (($type)(($type)1.0 + ($type)($y)) == ($type)1.0)
                  || ($type)(($type)(($type)1.0 + ($type)($y)) - ($type)1.0) != ($type)($y)
                 ) - 1];]])
            ],
            [break;])
          negepsilon_bits=`expr $negepsilon_bits + 1`; y="$y * ($type)0.5"
        done
        echo "/* Properties of type \`$type': */"
        echo "/* Largest n for which 1+2^(-n) is exactly represented is $epsilon_bits. */"
        echo "/* Largest n for which 1-2^(-n) is exactly represented is $negepsilon_bits. */"
        if test `expr $negepsilon_bits '<=' $epsilon_bits` = 1; then
          echo "#error \"No exponent jump at 1.0 for type $type!\""
        else
          if test `expr $negepsilon_bits '>' $epsilon_bits + 1` = 1; then
            echo "/* Base for type '$type' is 2^"`expr $negepsilon_bits - $epsilon_bits`
          fi
          echo "#define "`echo $type | sed -e 's, ,_,g'`"_mant_bits "`expr $epsilon_bits + 1`
        fi
        x="($type)1.0"
        i=$epsilon_bits
        while test $i != 0; do
          x="$x * ($type)0.5"
          i=`expr $i - 1`
        done
        x="($type)($x)"
        y1="($type)(($type)1.0 + ($type)5.0*$x)"
        y2="($type)(($type)1.0 + ($type)6.0*$x)"
        ys1="($type)(($type)1.0 + ($type)5.4*$x)"
        ys2="($type)(($type)1.0 + ($type)5.6*$x)"
        z1="($type)(($type)-1.0 + ($type)(-5.0)*$x)"
        z2="($type)(($type)-1.0 + ($type)(-6.0)*$x)"
        zs1="($type)(($type)-1.0 + ($type)(-5.4)*$x)"
        zs2="($type)(($type)-1.0 + ($type)(-5.6)*$x)"
        rounds=
        if test -z "$rounds"; then
          AC_COMPILE_IFELSE(
            [AC_LANG_PROGRAM([],
               [[typedef int verify[2*(
                  $ys1 == $y1 && $ys2 == $y2 && $zs1 == $z1 && $zs2 == $z2
                 ) - 1];]])
            ],
            [rounds=rounds_to_nearest])
        fi
        if test -z "$rounds"; then
          AC_COMPILE_IFELSE(
            [AC_LANG_PROGRAM([],
               [[typedef int verify[2*(
                  $ys1 == $y1 && $ys2 == $y1 && $zs1 == $z1 && $zs2 == $z1
                 ) - 1];]])
            ],
            [rounds=rounds_to_zero])
        fi
        if test -z "$rounds"; then
          AC_COMPILE_IFELSE(
            [AC_LANG_PROGRAM([],
               [[typedef int verify[2*(
                  $ys1 == $y2 && $ys2 == $y2 && $zs1 == $z1 && $zs2 == $z1
                 ) - 1];]])
            ],
            [rounds=rounds_to_infinity])
        fi
        if test -z "$rounds"; then
          AC_COMPILE_IFELSE(
            [AC_LANG_PROGRAM([],
               [[typedef int verify[2*(
                  $ys1 == $y1 && $ys2 == $y1 && $zs1 == $z2 && $zs2 == $z2
                 ) - 1];]])
            ],
            [rounds=rounds_to_minus_infinity])
        fi
        if test -n "$rounds"; then
          echo "#define "`echo $type | sed -e 's, ,_,g'`"_rounds $rounds"
        else
          echo "#error \"Unknown rounding mode for type $type!\""
        fi
        echo
      fi
    done
    dnl Words-in-a-double endianness test. Note that, assuming IEEE 754 format,
    dnl 2.5479915693083957     = { 0x40 0x04 0x62 0x49 0x67 0x65 0x4E 0x64 } ..bIgeNd
    dnl 1.4396527506122064e164 = { 0x62 0x04 0x00 0x00 0x4E 0x65 0x67 0x49 } b...NegI
    dnl 2.5495230282078065     = { 0x40 0x04 0x65 0x6C 0x54 0x54 0x69 0x4C } ..elTTiL
    dnl 1.4139248369879473e214 = { 0x6C 0x65 0x00 0x00 0x4C 0x69 0x54 0x54 } le..LiTT
    double_wordorder_bigendian_p=
    AC_COMPILE_IFELSE(
      [AC_LANG_PROGRAM([[
         double a[9] = {
           0, 2.5479915693083957, 0, 1.4396527506122064e164,
           0, 2.5495230282078065, 0, 1.4139248369879473e214,
           0 };
         ]],
         [])
      ],
      [if grep LiTTle conftest.$ac_objext >/dev/null; then
         double_wordorder_bigendian_p=0
       else
         if grep bIgeN conftest.$ac_objext >/dev/null; then
           double_wordorder_bigendian_p=1
         fi
       fi
      ])
    if test -n "$double_wordorder_bigendian_p"; then
      echo "#define double_wordorder_bigendian_p $double_wordorder_bigendian_p"
    else
      echo "/* Dazed and confused!  Better not define anything. */"
    fi
    echo
  } > "$cl_machine_file_h"
])