File: class.c

package info (click to toggle)
mlton 20100608-5
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 36,624 kB
  • sloc: ansic: 18,441; lisp: 2,879; makefile: 1,572; sh: 1,326; pascal: 256; asm: 97
file content (174 lines) | stat: -rw-r--r-- 3,829 bytes parent folder | download | duplicates (3)
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include "platform.h"

#if defined (HAS_FPCLASSIFY) && HAS_FPCLASSIFY

C_Int_t Real32_class (Real32_t f) {
  return fpclassify (f);
}

#elif defined (HAS_FPCLASSIFY32) && HAS_FPCLASSIFY32

C_Int_t Real32_class (Real32_t f) {
  return fpclassify32 (f);
}

#else

/* This code assumes IEEE 754/854.
 *
 * In little-endian memory, the 32 bits of a float are layed out as follows.
 *
 * d[0]  bits 7-0 of mantissa
 * d[1]  bits 15-8 of mantissa
 * d[2]  bit  0 of exponent
 *       bits 22-16 of mantissa
 * d[3]  sign bit
 *       bits 7-1 of exponent
 *
 * In big-endian memory, the 32 bits of a float are layed out as follows.
 *
 * d[3]  bits 7-0 of mantissa
 * d[2]  bits 15-8 of mantissa
 * d[1]  bit  0 of exponent
 *       bits 22-16 of mantissa
 * d[0]  sign bit
 *       bits 7-1 of exponent
 */

/* masks for least/most significant word */
#define EXPONENT_MASK32 0x7F800000
#define MANTISSA_MASK32 0x007FFFFF
#define SIGNBIT_MASK32  0x80000000
#define MANTISSA_HIGHBIT_MASK32 0x00400000

C_Int_t Real32_class (Real32_t f) {
  uint32_t word0;
  int res;

  /* Using memcpy;
   * Technically correct.
   */
  uint32_t words[1];
  memcpy(&words, &f, sizeof(Real32_t));
  word0 = words[0];
  /* Using union;
   * Technically undefined, but widely supported.
   */
  /*
  union {float f; uint32_t words[1];} fws;
  fws.f = f;
  word0 = fws.words[0];
  */

  if ((word0 & EXPONENT_MASK32) == EXPONENT_MASK32) {
    if (word0 & MANTISSA_MASK32)
      res = FP_NAN;
    else
      res = FP_INFINITE;
  } else if (word0 & EXPONENT_MASK32)
    res = FP_NORMAL;
  else if (word0 & MANTISSA_MASK32)
    res = FP_SUBNORMAL;
  else
    res = FP_ZERO;
  return res;
}

#endif


#if defined (HAS_FPCLASSIFY) && HAS_FPCLASSIFY

C_Int_t Real64_class (Real64_t d) {
  return fpclassify (d);
}

#elif defined (HAS_FPCLASSIFY64) && HAS_FPCLASSIFY64

C_Int_t Real64_class (Real64_t d) {
  return fpclassify64 (d);
}

#else

/* This code assumes IEEE 754/854.
 *
 * In little-endian memory, the 64 bits of a double are layed out as follows.
 *
 * d[0]  bits 7-0 of mantissa
 * d[1]  bits 15-8 of mantissa
 * d[2]  bits 23-16 of mantissa
 * d[3]  bits 31-24 of mantissa
 * d[4]  bits 39-32 of mantissa
 * d[5]  bits 47-40 of mantissa
 * d[6]  bits 3-0 of exponent
 *       bits 51-48 of mantissa
 * d[7]  sign bit
 *       bits 10-4 of exponent
 *
 * In big-endian memory, the 64 bits of a double are layed out as follows.
 *
 * d[7]  bits 7-0 of mantissa
 * d[6]  bits 15-8 of mantissa
 * d[5]  bits 23-16 of mantissa
 * d[4]  bits 31-24 of mantissa
 * d[3]  bits 39-32 of mantissa
 * d[2]  bits 47-40 of mantissa
 * d[1]  bits 3-0 of exponent
 *       bits 51-48 of mantissa
 * d[0]  sign bit
 *       bits 10-4 of exponent
 */

/* masks for most-significant word */
#define EXPONENT_MASK64 0x7FF00000
#define MANTISSA_MASK64 0x000FFFFF
#define SIGNBIT_MASK64  0x80000000
#define MANTISSA_HIGHBIT_MASK64 0x00080000

C_Int_t Real64_class (Real64_t d) {
  uint32_t word0, word1;
  int res;

  /* Using memcpy;
   * Technically correct.
   */
  uint32_t words[2];
  memcpy(&words, &d, sizeof(Real64_t));
  if (isBigEndian()) {
    word1 = words[0];
    word0 = words[1];
  } else {
    word0 = words[0];
    word1 = words[1];
  }
  /* Using union;
   * Technically undefined, but widely supported.
   */
  /*
  union {double d; uint32_t words[2];} dws;
  dws.d = d;
  if (isBigEndian()) {
    word1 = dws.words[0];
    word0 = dws.words[1];
  } else {
    word0 = dws.words[0];
    word1 = dws.words[1];
  }
  */

  if ((word1 & EXPONENT_MASK64) == EXPONENT_MASK64) {
    if (word0 or (word1 & MANTISSA_MASK64))
      res = FP_NAN;
    else
      res = FP_INFINITE;
  } else if (word1 & EXPONENT_MASK64)
    res = FP_NORMAL;
  else if (word0 or (word1 & MANTISSA_MASK64))
    res = FP_SUBNORMAL;
  else
    res = FP_ZERO;
  return res;
}

#endif