Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
wsieee754.h File Reference

Go to the source code of this file.

Enumerations

enum  WsIeee754Result { WS_IEEE754_OK, WS_IEEE754_NAN, WS_IEEE754_POSITIVE_INF, WS_IEEE754_NEGATIVE_INF }
 

Functions

WsIeee754Result ws_ieee754_encode_single (double value, unsigned char *buf)
 
WsIeee754Result ws_ieee754_decode_single (unsigned char *buf, double *value_return)
 
WsUInt32 ws_ieee754_single_get_sign (unsigned char *buf)
 
WsUInt32 ws_ieee754_single_get_exp (unsigned char *buf)
 
WsUInt32 ws_ieee754_single_get_mant (unsigned char *buf)
 

Variables

unsigned char ws_ieee754_nan [4]
 
unsigned char ws_ieee754_positive_inf [4]
 
unsigned char ws_ieee754_negative_inf [4]
 

Enumeration Type Documentation

Enumerator
WS_IEEE754_OK 
WS_IEEE754_NAN 
WS_IEEE754_POSITIVE_INF 
WS_IEEE754_NEGATIVE_INF 

Definition at line 77 of file wsieee754.h.

78 {
79  /* The operation was successful. */
81 
82  /* The value is `Not a Number' NaN. */
84 
85  /* The valueis positive infinity. */
87 
88  /* The value is negative infinity. */
WsIeee754Result
Definition: wsieee754.h:77

Function Documentation

WsIeee754Result ws_ieee754_decode_single ( unsigned char *  buf,
double *  value_return 
)

Definition at line 199 of file wsieee754.c.

References WS_IEEE754_NAN, WS_IEEE754_NEGATIVE_INF, WS_IEEE754_OK, WS_IEEE754_POSITIVE_INF, WS_IEEE754_SINGLE_BIAS, ws_ieee754_single_get_exp(), ws_ieee754_single_get_mant(), ws_ieee754_single_get_sign(), and WS_IEEE754_SINGLE_MANT_SIZE.

Referenced by ws_bc_decode().

201 {
205  double value;
206  int i;
207 
208  /* Check the special cases where exponent is all 1. */
209  if (exp == 0xff) {
210  if (mant == 0)
212 
213  return WS_IEEE754_NAN;
214  }
215 
216  /* Expand the mantissa. */
217  value = 0.0;
218  for (i = 0; i < WS_IEEE754_SINGLE_MANT_SIZE; i++) {
219  if (mant & 0x1)
220  value += 1.0;
221 
222  value /= 2.0;
223  mant >>= 1;
224  }
225 
226  /* Check the `unnormalized' vs. `normal form'. */
227  if (exp == 0)
228  /* This is a `unnormalized' number. */
229  exp = -126;
230  else {
231  /* This is a standard case. */
232  value += 1.0;
233  exp -= WS_IEEE754_SINGLE_BIAS;
234  }
235 
236  /* Handle exponents. */
237  while (exp > 0) {
238  value *= 2;
239  exp--;
240  }
241  while (exp < 0) {
242  value /= 2;
243  exp++;
244  }
245 
246  /* Finally notify sign. */
247  if (sign)
248  value = -value;
249 
250  *value_return = value;
251 
252  return WS_IEEE754_OK;
253 }
#define WS_IEEE754_SINGLE_BIAS
Definition: wsieee754.c:77
unsigned long WsUInt32
Definition: wsint.h:122
WsUInt32 ws_ieee754_single_get_exp(unsigned char *buf)
Definition: wsieee754.c:262
WsUInt32 ws_ieee754_single_get_mant(unsigned char *buf)
Definition: wsieee754.c:273
WsUInt32 ws_ieee754_single_get_sign(unsigned char *buf)
Definition: wsieee754.c:256
#define WS_IEEE754_SINGLE_MANT_SIZE
Definition: wsieee754.c:76
signed long WsInt32
Definition: wsint.h:121
WsIeee754Result ws_ieee754_encode_single ( double  value,
unsigned char *  buf 
)

Definition at line 94 of file wsieee754.c.

References gw_assert(), WS_IEEE754_NEGATIVE_INF, WS_IEEE754_OK, WS_IEEE754_POSITIVE_INF, WS_IEEE754_SINGLE_BIAS, WS_IEEE754_SINGLE_EXP_MAX, WS_IEEE754_SINGLE_EXP_MIN, and WS_IEEE754_SINGLE_MANT_SIZE.

Referenced by read_float_from_exp(), and ws_bc_encode().

95 {
96  int sign = 0;
97  WsInt32 exp = 0;
98  WsUInt32 mant = 0;
99  int i;
101 
102  /* The sign bit. */
103  if (value < 0.0) {
104  sign = 1;
105  value = -value;
106  }
107 
108  /* Scale the value so that: 1 <= mantissa < 2. */
109  if (value > 1.0) {
110  /* The exponent is positive. */
111  while (value >= 2.0 && exp <= WS_IEEE754_SINGLE_EXP_MAX) {
112  value /= 2.0;
113  exp++;
114  }
115  if (exp > WS_IEEE754_SINGLE_EXP_MAX) {
116  /* Overflow => infinity. */
117  exp = 0xff;
118 
119  if (sign)
120  result = WS_IEEE754_NEGATIVE_INF;
121  else
122  result = WS_IEEE754_POSITIVE_INF;
123 
124  goto done;
125  }
126 
127  /* The 1 is implicit. */
128  value -= 1;
129  } else {
130  /* The exponent is negative. */
131  while (value < 1.0 && exp > WS_IEEE754_SINGLE_EXP_MIN) {
132  value *= 2.0;
133  exp--;
134  }
135  if (value >= 1.0) {
136  /* We managed to get the number to the normal form. Let's
137  remote the implicit 1 from the value. */
138  gw_assert(value >= 1.0);
139  value -= 1.0;
140  } else {
141  /* The number is still smaller than 1. We just try to
142  present the remaining stuff in our mantissa. If that
143  fails, we fall back to 0.0. We mark exp to -127 (after
144  bias it is 0) to mark this unnormalized form. */
145  exp--;
146  gw_assert(exp == -127);
147  }
148  }
149 
150  for (i = 0; i < WS_IEEE754_SINGLE_MANT_SIZE; i++) {
151  value *= 2.0;
152  mant <<= 1;
153 
154  if (value >= 1.0) {
155  mant |= 1;
156  value -= 1.0;
157  }
158  }
159 
160  /* Handle rounding. Intel seems to round 0.5 down so to be
161  compatible, our check is > instead of >=. */
162  if (value * 2.0 > 1.0) {
163  mant++;
164  if (mant == 0x800000) {
165  /* This we the really worst case. The rounding rounds the
166  mant up to 2.0. So we must increase the exponent by one.
167  This may then result an overflow in the exponent which
168  converts our number to infinity. */
169  mant = 0;
170  exp++;
171 
172  if (exp > WS_IEEE754_SINGLE_EXP_MAX) {
173  /* Overflow => infinity. */
174  exp = 0xff;
175  goto done;
176  }
177  }
178  }
179 
180  /* Handle biased exponent. */
181  exp += WS_IEEE754_SINGLE_BIAS;
182 
183 done:
184 
185  /* Encode the value to the buffer. */
186 
187  mant |= exp << 23;
188  mant |= sign << 31;
189 
190  buf[3] = (mant & 0x000000ff);
191  buf[2] = (mant & 0x0000ff00) >> 8;
192  buf[1] = (mant & 0x00ff0000) >> 16;
193  buf[0] = (mant & 0xff000000) >> 24;
194 
195  return result;
196 }
#define WS_IEEE754_SINGLE_BIAS
Definition: wsieee754.c:77
unsigned long WsUInt32
Definition: wsint.h:122
WsIeee754Result
Definition: wsieee754.h:77
#define WS_IEEE754_SINGLE_MANT_SIZE
Definition: wsieee754.c:76
gw_assert(wtls_machine->packet_to_send!=NULL)
signed long WsInt32
Definition: wsint.h:121
#define WS_IEEE754_SINGLE_EXP_MIN
Definition: wsieee754.c:79
#define WS_IEEE754_SINGLE_EXP_MAX
Definition: wsieee754.c:80
WsUInt32 ws_ieee754_single_get_exp ( unsigned char *  buf)

Definition at line 262 of file wsieee754.c.

Referenced by ws_ieee754_decode_single().

263 {
264  WsUInt32 value = buf[0] & 0x7f;
265 
266  value <<= 1;
267  value |= (buf[1] & 0x80) >> 7;
268 
269  return value;
270 }
unsigned long WsUInt32
Definition: wsint.h:122
WsUInt32 ws_ieee754_single_get_mant ( unsigned char *  buf)

Definition at line 273 of file wsieee754.c.

Referenced by ws_ieee754_decode_single().

274 {
275  WsUInt32 value = buf[1] & 0x7f;
276 
277  value <<= 8;
278  value |= buf[2];
279 
280  value <<= 8;
281  value |= buf[3];
282 
283  return value;
284 }
unsigned long WsUInt32
Definition: wsint.h:122
WsUInt32 ws_ieee754_single_get_sign ( unsigned char *  buf)

Definition at line 256 of file wsieee754.c.

Referenced by ws_ieee754_decode_single().

257 {
258  return (buf[0] & 0x80) >> 7;
259 }

Variable Documentation

unsigned char ws_ieee754_nan[4]

Definition at line 86 of file wsieee754.c.

Referenced by ws_bc_encode().

unsigned char ws_ieee754_negative_inf[4]

Definition at line 90 of file wsieee754.c.

Referenced by ws_bc_encode().

unsigned char ws_ieee754_positive_inf[4]

Definition at line 88 of file wsieee754.c.

Referenced by ws_bc_encode().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.