ieee754io.c revision 1.6 1 1.5 christos /* $NetBSD: ieee754io.c,v 1.6 2024/08/18 20:47:17 christos Exp $ */
2 1.1 kardel
3 1.1 kardel /*
4 1.1 kardel * /src/NTP/ntp4-dev/libntp/ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
5 1.1 kardel *
6 1.1 kardel * ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
7 1.1 kardel *
8 1.2 christos * $Created: Sun Jul 13 09:12:02 1997 $
9 1.1 kardel *
10 1.1 kardel * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
11 1.1 kardel *
12 1.1 kardel * Redistribution and use in source and binary forms, with or without
13 1.1 kardel * modification, are permitted provided that the following conditions
14 1.1 kardel * are met:
15 1.1 kardel * 1. Redistributions of source code must retain the above copyright
16 1.1 kardel * notice, this list of conditions and the following disclaimer.
17 1.1 kardel * 2. Redistributions in binary form must reproduce the above copyright
18 1.1 kardel * notice, this list of conditions and the following disclaimer in the
19 1.1 kardel * documentation and/or other materials provided with the distribution.
20 1.1 kardel * 3. Neither the name of the author nor the names of its contributors
21 1.1 kardel * may be used to endorse or promote products derived from this software
22 1.1 kardel * without specific prior written permission.
23 1.1 kardel *
24 1.1 kardel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 1.1 kardel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 1.1 kardel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 1.1 kardel * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28 1.1 kardel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 1.1 kardel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 1.1 kardel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 1.1 kardel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 1.1 kardel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 1.1 kardel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 1.1 kardel * SUCH DAMAGE.
35 1.1 kardel *
36 1.1 kardel */
37 1.1 kardel
38 1.1 kardel #ifdef HAVE_CONFIG_H
39 1.1 kardel #include "config.h"
40 1.1 kardel #endif
41 1.1 kardel
42 1.1 kardel #include <stdio.h>
43 1.1 kardel #include "l_stdlib.h"
44 1.1 kardel #include "ntp_stdlib.h"
45 1.1 kardel #include "ntp_fp.h"
46 1.1 kardel #include "ieee754io.h"
47 1.1 kardel
48 1.1 kardel static unsigned char get_byte (unsigned char *, offsets_t, int *);
49 1.1 kardel #ifdef __not_yet__
50 1.1 kardel static void put_byte (unsigned char *, offsets_t, int *, unsigned char);
51 1.1 kardel #endif
52 1.1 kardel
53 1.1 kardel #ifdef LIBDEBUG
54 1.1 kardel
55 1.1 kardel static char *
56 1.1 kardel fmt_blong(
57 1.1 kardel unsigned long val,
58 1.1 kardel int cnt
59 1.1 kardel )
60 1.1 kardel {
61 1.1 kardel char *buf, *s;
62 1.1 kardel int i = cnt;
63 1.1 kardel
64 1.1 kardel val <<= 32 - cnt;
65 1.1 kardel LIB_GETBUF(buf);
66 1.1 kardel s = buf;
67 1.1 kardel
68 1.1 kardel while (i--)
69 1.1 kardel {
70 1.1 kardel if (val & 0x80000000)
71 1.1 kardel {
72 1.1 kardel *s++ = '1';
73 1.1 kardel }
74 1.1 kardel else
75 1.1 kardel {
76 1.1 kardel *s++ = '0';
77 1.1 kardel }
78 1.1 kardel val <<= 1;
79 1.1 kardel }
80 1.1 kardel *s = '\0';
81 1.1 kardel return buf;
82 1.1 kardel }
83 1.1 kardel
84 1.1 kardel static char *
85 1.1 kardel fmt_flt(
86 1.1 kardel unsigned int sign,
87 1.1 kardel unsigned long mh,
88 1.1 kardel unsigned long ml,
89 1.1 kardel unsigned long ch
90 1.1 kardel )
91 1.1 kardel {
92 1.2 christos char *buf;
93 1.1 kardel
94 1.2 christos LIB_GETBUF(buf);
95 1.2 christos snprintf(buf, LIB_BUFLENGTH, "%c %s %s %s", sign ? '-' : '+',
96 1.2 christos fmt_blong(ch, 11),
97 1.2 christos fmt_blong(mh, 20),
98 1.2 christos fmt_blong(ml, 32));
99 1.2 christos
100 1.2 christos return buf;
101 1.1 kardel }
102 1.1 kardel
103 1.1 kardel static char *
104 1.1 kardel fmt_hex(
105 1.1 kardel unsigned char *bufp,
106 1.1 kardel int length
107 1.1 kardel )
108 1.1 kardel {
109 1.2 christos char * buf;
110 1.2 christos char hex[4];
111 1.2 christos int i;
112 1.2 christos
113 1.2 christos LIB_GETBUF(buf);
114 1.2 christos buf[0] = '\0';
115 1.2 christos for (i = 0; i < length; i++) {
116 1.2 christos snprintf(hex, sizeof(hex), "%02x", bufp[i]);
117 1.2 christos strlcat(buf, hex, LIB_BUFLENGTH);
118 1.2 christos }
119 1.1 kardel
120 1.2 christos return buf;
121 1.1 kardel }
122 1.1 kardel
123 1.1 kardel #endif
124 1.1 kardel
125 1.1 kardel static unsigned char
126 1.1 kardel get_byte(
127 1.1 kardel unsigned char *bufp,
128 1.1 kardel offsets_t offset,
129 1.1 kardel int *fieldindex
130 1.1 kardel )
131 1.1 kardel {
132 1.1 kardel unsigned char val;
133 1.1 kardel
134 1.1 kardel val = *(bufp + offset[*fieldindex]);
135 1.1 kardel #ifdef LIBDEBUG
136 1.1 kardel if (debug > 4)
137 1.1 kardel printf("fetchieee754: getbyte(0x%08x, %d) = 0x%02x\n", (unsigned int)(bufp)+offset[*fieldindex], *fieldindex, val);
138 1.1 kardel #endif
139 1.1 kardel (*fieldindex)++;
140 1.1 kardel return val;
141 1.1 kardel }
142 1.1 kardel
143 1.1 kardel #ifdef __not_yet__
144 1.1 kardel static void
145 1.1 kardel put_byte(
146 1.1 kardel unsigned char *bufp,
147 1.1 kardel offsets_t offsets,
148 1.1 kardel int *fieldindex,
149 1.1 kardel unsigned char val
150 1.1 kardel )
151 1.1 kardel {
152 1.1 kardel *(bufp + offsets[*fieldindex]) = val;
153 1.1 kardel (*fieldindex)++;
154 1.1 kardel }
155 1.1 kardel #endif
156 1.1 kardel
157 1.1 kardel /*
158 1.1 kardel * make conversions to and from external IEEE754 formats and internal
159 1.1 kardel * NTP FP format.
160 1.1 kardel */
161 1.1 kardel int
162 1.1 kardel fetch_ieee754(
163 1.1 kardel unsigned char **buffpp,
164 1.1 kardel int size,
165 1.1 kardel l_fp *lfpp,
166 1.1 kardel offsets_t offsets
167 1.1 kardel )
168 1.1 kardel {
169 1.1 kardel unsigned char *bufp = *buffpp;
170 1.1 kardel unsigned int sign;
171 1.1 kardel unsigned int bias;
172 1.1 kardel unsigned int maxexp;
173 1.1 kardel int mbits;
174 1.1 kardel u_long mantissa_low;
175 1.1 kardel u_long mantissa_high;
176 1.1 kardel u_long characteristic;
177 1.1 kardel long exponent;
178 1.1 kardel #ifdef LIBDEBUG
179 1.1 kardel int length;
180 1.1 kardel #endif
181 1.1 kardel unsigned char val;
182 1.1 kardel int fieldindex = 0;
183 1.1 kardel
184 1.1 kardel switch (size)
185 1.1 kardel {
186 1.1 kardel case IEEE_DOUBLE:
187 1.1 kardel #ifdef LIBDEBUG
188 1.1 kardel length = 8;
189 1.1 kardel #endif
190 1.1 kardel mbits = 52;
191 1.1 kardel bias = 1023;
192 1.1 kardel maxexp = 2047;
193 1.1 kardel break;
194 1.1 kardel
195 1.1 kardel case IEEE_SINGLE:
196 1.1 kardel #ifdef LIBDEBUG
197 1.1 kardel length = 4;
198 1.1 kardel #endif
199 1.1 kardel mbits = 23;
200 1.1 kardel bias = 127;
201 1.1 kardel maxexp = 255;
202 1.1 kardel break;
203 1.1 kardel
204 1.1 kardel default:
205 1.1 kardel return IEEE_BADCALL;
206 1.1 kardel }
207 1.1 kardel
208 1.1 kardel val = get_byte(bufp, offsets, &fieldindex); /* fetch sign byte & first part of characteristic */
209 1.1 kardel
210 1.1 kardel sign = (val & 0x80) != 0;
211 1.1 kardel characteristic = (val & 0x7F);
212 1.1 kardel
213 1.1 kardel val = get_byte(bufp, offsets, &fieldindex); /* fetch rest of characteristic and start of mantissa */
214 1.1 kardel
215 1.1 kardel switch (size)
216 1.1 kardel {
217 1.1 kardel case IEEE_SINGLE:
218 1.1 kardel characteristic <<= 1;
219 1.1 kardel characteristic |= (val & 0x80) != 0; /* grab last characteristic bit */
220 1.1 kardel
221 1.1 kardel mantissa_high = 0;
222 1.1 kardel
223 1.1 kardel mantissa_low = (val &0x7F) << 16;
224 1.2 christos mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
225 1.1 kardel mantissa_low |= get_byte(bufp, offsets, &fieldindex);
226 1.1 kardel break;
227 1.1 kardel
228 1.1 kardel case IEEE_DOUBLE:
229 1.1 kardel characteristic <<= 4;
230 1.1 kardel characteristic |= (val & 0xF0) >> 4; /* grab lower characteristic bits */
231 1.1 kardel
232 1.1 kardel mantissa_high = (val & 0x0F) << 16;
233 1.2 christos mantissa_high |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
234 1.1 kardel mantissa_high |= get_byte(bufp, offsets, &fieldindex);
235 1.1 kardel
236 1.2 christos mantissa_low = (u_long)get_byte(bufp, offsets, &fieldindex) << 24;
237 1.2 christos mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 16;
238 1.2 christos mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
239 1.1 kardel mantissa_low |= get_byte(bufp, offsets, &fieldindex);
240 1.1 kardel break;
241 1.1 kardel
242 1.1 kardel default:
243 1.1 kardel return IEEE_BADCALL;
244 1.1 kardel }
245 1.1 kardel #ifdef LIBDEBUG
246 1.1 kardel if (debug > 4)
247 1.1 kardel {
248 1.1 kardel double d;
249 1.1 kardel float f;
250 1.1 kardel
251 1.1 kardel if (size == IEEE_SINGLE)
252 1.1 kardel {
253 1.1 kardel int i;
254 1.1 kardel
255 1.1 kardel for (i = 0; i < length; i++)
256 1.1 kardel {
257 1.1 kardel *((unsigned char *)(&f)+i) = *(*buffpp + offsets[i]);
258 1.1 kardel }
259 1.1 kardel d = f;
260 1.1 kardel }
261 1.1 kardel else
262 1.1 kardel {
263 1.1 kardel int i;
264 1.1 kardel
265 1.1 kardel for (i = 0; i < length; i++)
266 1.1 kardel {
267 1.1 kardel *((unsigned char *)(&d)+i) = *(*buffpp + offsets[i]);
268 1.1 kardel }
269 1.1 kardel }
270 1.1 kardel
271 1.1 kardel printf("fetchieee754: FP: %s -> %s -> %e(=%s)\n", fmt_hex(*buffpp, length),
272 1.1 kardel fmt_flt(sign, mantissa_high, mantissa_low, characteristic),
273 1.1 kardel d, fmt_hex((unsigned char *)&d, length));
274 1.1 kardel }
275 1.1 kardel #endif
276 1.1 kardel
277 1.1 kardel *buffpp += fieldindex;
278 1.1 kardel
279 1.1 kardel /*
280 1.1 kardel * detect funny numbers
281 1.1 kardel */
282 1.1 kardel if (characteristic == maxexp)
283 1.1 kardel {
284 1.1 kardel /*
285 1.1 kardel * NaN or Infinity
286 1.1 kardel */
287 1.1 kardel if (mantissa_low || mantissa_high)
288 1.1 kardel {
289 1.1 kardel /*
290 1.1 kardel * NaN
291 1.1 kardel */
292 1.1 kardel return IEEE_NAN;
293 1.1 kardel }
294 1.1 kardel else
295 1.1 kardel {
296 1.1 kardel /*
297 1.1 kardel * +Inf or -Inf
298 1.1 kardel */
299 1.1 kardel return sign ? IEEE_NEGINFINITY : IEEE_POSINFINITY;
300 1.1 kardel }
301 1.1 kardel }
302 1.1 kardel else
303 1.1 kardel {
304 1.1 kardel /*
305 1.1 kardel * collect real numbers
306 1.1 kardel */
307 1.1 kardel
308 1.1 kardel L_CLR(lfpp);
309 1.1 kardel
310 1.1 kardel /*
311 1.1 kardel * check for overflows
312 1.1 kardel */
313 1.1 kardel exponent = characteristic - bias;
314 1.1 kardel
315 1.1 kardel if (exponent > 31) /* sorry - hardcoded */
316 1.1 kardel {
317 1.1 kardel /*
318 1.1 kardel * overflow only in respect to NTP-FP representation
319 1.1 kardel */
320 1.1 kardel return sign ? IEEE_NEGOVERFLOW : IEEE_POSOVERFLOW;
321 1.1 kardel }
322 1.1 kardel else
323 1.1 kardel {
324 1.1 kardel int frac_offset; /* where the fraction starts */
325 1.1 kardel
326 1.1 kardel frac_offset = mbits - exponent;
327 1.1 kardel
328 1.1 kardel if (characteristic == 0)
329 1.1 kardel {
330 1.1 kardel /*
331 1.1 kardel * de-normalized or tiny number - fits only as 0
332 1.1 kardel */
333 1.1 kardel return IEEE_OK;
334 1.1 kardel }
335 1.1 kardel else
336 1.1 kardel {
337 1.1 kardel /*
338 1.1 kardel * adjust for implied 1
339 1.1 kardel */
340 1.1 kardel if (mbits > 31)
341 1.1 kardel mantissa_high |= 1 << (mbits - 32);
342 1.1 kardel else
343 1.1 kardel mantissa_low |= 1 << mbits;
344 1.1 kardel
345 1.1 kardel /*
346 1.1 kardel * take mantissa apart - if only all machine would support
347 1.1 kardel * 64 bit operations 8-(
348 1.1 kardel */
349 1.1 kardel if (frac_offset > mbits)
350 1.1 kardel {
351 1.1 kardel lfpp->l_ui = 0; /* only fractional number */
352 1.1 kardel frac_offset -= mbits + 1; /* will now contain right shift count - 1*/
353 1.1 kardel if (mbits > 31)
354 1.1 kardel {
355 1.1 kardel lfpp->l_uf = mantissa_high << (63 - mbits);
356 1.1 kardel lfpp->l_uf |= mantissa_low >> (mbits - 33);
357 1.1 kardel lfpp->l_uf >>= frac_offset;
358 1.1 kardel }
359 1.1 kardel else
360 1.1 kardel {
361 1.1 kardel lfpp->l_uf = mantissa_low >> frac_offset;
362 1.1 kardel }
363 1.1 kardel }
364 1.1 kardel else
365 1.1 kardel {
366 1.1 kardel if (frac_offset > 32)
367 1.1 kardel {
368 1.1 kardel /*
369 1.1 kardel * must split in high word
370 1.1 kardel */
371 1.1 kardel lfpp->l_ui = mantissa_high >> (frac_offset - 32);
372 1.1 kardel lfpp->l_uf = (mantissa_high & ((1 << (frac_offset - 32)) - 1)) << (64 - frac_offset);
373 1.1 kardel lfpp->l_uf |= mantissa_low >> (frac_offset - 32);
374 1.1 kardel }
375 1.1 kardel else
376 1.1 kardel {
377 1.1 kardel /*
378 1.1 kardel * must split in low word
379 1.1 kardel */
380 1.1 kardel lfpp->l_ui = mantissa_high << (32 - frac_offset);
381 1.1 kardel lfpp->l_ui |= (mantissa_low >> frac_offset) & ((1 << (32 - frac_offset)) - 1);
382 1.1 kardel lfpp->l_uf = (mantissa_low & ((1 << frac_offset) - 1)) << (32 - frac_offset);
383 1.1 kardel }
384 1.1 kardel }
385 1.1 kardel
386 1.1 kardel /*
387 1.1 kardel * adjust for sign
388 1.1 kardel */
389 1.1 kardel if (sign)
390 1.1 kardel {
391 1.1 kardel L_NEG(lfpp);
392 1.1 kardel }
393 1.1 kardel
394 1.1 kardel return IEEE_OK;
395 1.1 kardel }
396 1.1 kardel }
397 1.1 kardel }
398 1.1 kardel }
399 1.6 christos
400 1.6 christos /*
401 1.6 christos * DLH: This function is currently unused in ntpd. If you think about
402 1.6 christos * using it, be sure it does what you intend. I notice the bufpp arg
403 1.6 christos * is never referenced, and the calculated mantissa_high & mantissa_low
404 1.6 christos * are only referenced in debug output. It seems they're supposed to
405 1.6 christos * be composed into an ieee754-format float and stored at *bufpp or
406 1.6 christos * possibly **bufpp. Brought to my attention by this:
407 1.6 christos *
408 1.6 christos * ieee754io.c:414:10: warning: variable 'mantissa_low' set but not used
409 1.6 christos * [-Wunused-but-set-variable]
410 1.6 christos *
411 1.6 christos * To quiet it I'm #ifdef'ing the function away for now, here and below
412 1.6 christos * the call to it in main().
413 1.6 christos */
414 1.6 christos #ifdef PUT_IEEE754_UNUSED_FUNC
415 1.1 kardel int
416 1.1 kardel put_ieee754(
417 1.1 kardel unsigned char **bufpp,
418 1.1 kardel int size,
419 1.1 kardel l_fp *lfpp,
420 1.1 kardel offsets_t offsets
421 1.1 kardel )
422 1.1 kardel {
423 1.1 kardel l_fp outlfp;
424 1.1 kardel #ifdef LIBDEBUG
425 1.1 kardel unsigned int sign;
426 1.1 kardel unsigned int bias;
427 1.1 kardel #endif
428 1.1 kardel /*unsigned int maxexp;*/
429 1.1 kardel int mbits;
430 1.1 kardel int msb;
431 1.1 kardel u_long mantissa_low = 0;
432 1.1 kardel u_long mantissa_high = 0;
433 1.1 kardel #ifdef LIBDEBUG
434 1.1 kardel u_long characteristic = 0;
435 1.1 kardel long exponent;
436 1.1 kardel #endif
437 1.1 kardel /*int length;*/
438 1.1 kardel unsigned long mask;
439 1.1 kardel
440 1.1 kardel outlfp = *lfpp;
441 1.1 kardel
442 1.1 kardel switch (size)
443 1.1 kardel {
444 1.1 kardel case IEEE_DOUBLE:
445 1.1 kardel /*length = 8;*/
446 1.1 kardel mbits = 52;
447 1.1 kardel #ifdef LIBDEBUG
448 1.1 kardel bias = 1023;
449 1.1 kardel #endif
450 1.1 kardel /*maxexp = 2047;*/
451 1.1 kardel break;
452 1.1 kardel
453 1.1 kardel case IEEE_SINGLE:
454 1.1 kardel /*length = 4;*/
455 1.1 kardel mbits = 23;
456 1.1 kardel #ifdef LIBDEBUG
457 1.1 kardel bias = 127;
458 1.1 kardel #endif
459 1.1 kardel /*maxexp = 255;*/
460 1.1 kardel break;
461 1.1 kardel
462 1.1 kardel default:
463 1.1 kardel return IEEE_BADCALL;
464 1.1 kardel }
465 1.1 kardel
466 1.1 kardel /*
467 1.1 kardel * find sign
468 1.1 kardel */
469 1.1 kardel if (L_ISNEG(&outlfp))
470 1.1 kardel {
471 1.1 kardel L_NEG(&outlfp);
472 1.1 kardel #ifdef LIBDEBUG
473 1.1 kardel sign = 1;
474 1.1 kardel #endif
475 1.1 kardel }
476 1.1 kardel else
477 1.1 kardel {
478 1.1 kardel #ifdef LIBDEBUG
479 1.1 kardel sign = 0;
480 1.1 kardel #endif
481 1.1 kardel }
482 1.1 kardel
483 1.1 kardel if (L_ISZERO(&outlfp))
484 1.1 kardel {
485 1.1 kardel #ifdef LIBDEBUG
486 1.1 kardel exponent = mantissa_high = mantissa_low = 0; /* true zero */
487 1.1 kardel #endif
488 1.1 kardel }
489 1.1 kardel else
490 1.1 kardel {
491 1.1 kardel /*
492 1.1 kardel * find number of significant integer bits
493 1.1 kardel */
494 1.1 kardel mask = 0x80000000;
495 1.1 kardel if (outlfp.l_ui)
496 1.1 kardel {
497 1.1 kardel msb = 63;
498 1.1 kardel while (mask && ((outlfp.l_ui & mask) == 0))
499 1.1 kardel {
500 1.1 kardel mask >>= 1;
501 1.1 kardel msb--;
502 1.1 kardel }
503 1.1 kardel }
504 1.1 kardel else
505 1.1 kardel {
506 1.1 kardel msb = 31;
507 1.1 kardel while (mask && ((outlfp.l_uf & mask) == 0))
508 1.1 kardel {
509 1.1 kardel mask >>= 1;
510 1.1 kardel msb--;
511 1.1 kardel }
512 1.1 kardel }
513 1.1 kardel
514 1.1 kardel switch (size)
515 1.1 kardel {
516 1.1 kardel case IEEE_SINGLE:
517 1.1 kardel mantissa_high = 0;
518 1.1 kardel if (msb >= 32)
519 1.1 kardel {
520 1.1 kardel mantissa_low = (outlfp.l_ui & ((1 << (msb - 32)) - 1)) << (mbits - (msb - 32));
521 1.1 kardel mantissa_low |= outlfp.l_uf >> (mbits - (msb - 32));
522 1.1 kardel }
523 1.1 kardel else
524 1.1 kardel {
525 1.1 kardel mantissa_low = (outlfp.l_uf << (mbits - msb)) & ((1 << mbits) - 1);
526 1.1 kardel }
527 1.1 kardel break;
528 1.1 kardel
529 1.1 kardel case IEEE_DOUBLE:
530 1.1 kardel if (msb >= 32)
531 1.1 kardel {
532 1.1 kardel mantissa_high = (outlfp.l_ui << (mbits - msb)) & ((1 << (mbits - 32)) - 1);
533 1.1 kardel mantissa_high |= outlfp.l_uf >> (32 - (mbits - msb));
534 1.1 kardel mantissa_low = (outlfp.l_ui & ((1 << (msb - mbits)) - 1)) << (32 - (msb - mbits));
535 1.1 kardel mantissa_low |= outlfp.l_uf >> (msb - mbits);
536 1.1 kardel }
537 1.1 kardel else
538 1.1 kardel {
539 1.1 kardel mantissa_high = outlfp.l_uf << (mbits - 32 - msb);
540 1.1 kardel mantissa_low = outlfp.l_uf << (mbits - 32);
541 1.1 kardel }
542 1.1 kardel }
543 1.1 kardel
544 1.1 kardel #ifdef LIBDEBUG
545 1.1 kardel exponent = msb - 32;
546 1.1 kardel characteristic = exponent + bias;
547 1.1 kardel
548 1.1 kardel if (debug > 4)
549 1.1 kardel printf("FP: %s\n", fmt_flt(sign, mantissa_high, mantissa_low, characteristic));
550 1.1 kardel #endif
551 1.1 kardel }
552 1.1 kardel return IEEE_OK;
553 1.1 kardel }
554 1.6 christos #endif /* PUT_IEEE754_UNUSED_FUNC */
555 1.1 kardel
556 1.1 kardel
557 1.1 kardel #if defined(DEBUG) && defined(LIBDEBUG)
558 1.1 kardel int main(
559 1.1 kardel int argc,
560 1.1 kardel char **argv
561 1.1 kardel )
562 1.1 kardel {
563 1.1 kardel static offsets_t native_off = { 0, 1, 2, 3, 4, 5, 6, 7 };
564 1.1 kardel double f = 1.0;
565 1.1 kardel double *f_p = &f;
566 1.1 kardel l_fp fp;
567 1.1 kardel
568 1.1 kardel if (argc == 2)
569 1.1 kardel {
570 1.1 kardel if (sscanf(argv[1], "%lf", &f) != 1)
571 1.1 kardel {
572 1.1 kardel printf("cannot convert %s to a float\n", argv[1]);
573 1.1 kardel return 1;
574 1.1 kardel }
575 1.1 kardel }
576 1.1 kardel
577 1.1 kardel printf("double: %s %s\n", fmt_blong(*(unsigned long *)&f, 32), fmt_blong(*(unsigned long *)((char *)(&f)+4), 32));
578 1.1 kardel printf("fetch from %f = %d\n", f, fetch_ieee754((void *)&f_p, IEEE_DOUBLE, &fp, native_off));
579 1.1 kardel printf("fp [%s %s] = %s\n", fmt_blong(fp.l_ui, 32), fmt_blong(fp.l_uf, 32), mfptoa(fp.l_ui, fp.l_uf, 15));
580 1.1 kardel f_p = &f;
581 1.6 christos #ifdef PUT_IEEE754_UNUSED_FUNC
582 1.1 kardel put_ieee754((void *)&f_p, IEEE_DOUBLE, &fp, native_off);
583 1.6 christos /* there should be a check on *f_p (f) having the expected result here */
584 1.6 christos #endif /* PUT_IEEE754_UNUSED_FUNC */
585 1.6 christos
586 1.1 kardel return 0;
587 1.1 kardel }
588 1.1 kardel
589 1.1 kardel #endif
590 1.1 kardel /*
591 1.1 kardel * History:
592 1.1 kardel *
593 1.1 kardel * ieee754io.c,v
594 1.1 kardel * Revision 4.12 2005/04/16 17:32:10 kardel
595 1.1 kardel * update copyright
596 1.1 kardel *
597 1.1 kardel * Revision 4.11 2004/11/14 15:29:41 kardel
598 1.1 kardel * support PPSAPI, upgrade Copyright to Berkeley style
599 1.1 kardel *
600 1.1 kardel * Revision 4.8 1999/02/21 12:17:36 kardel
601 1.1 kardel * 4.91f reconcilation
602 1.1 kardel *
603 1.1 kardel * Revision 4.7 1999/02/21 11:26:03 kardel
604 1.1 kardel * renamed index to fieldindex to avoid index() name clash
605 1.1 kardel *
606 1.1 kardel * Revision 4.6 1998/11/15 20:27:52 kardel
607 1.1 kardel * Release 4.0.73e13 reconcilation
608 1.1 kardel *
609 1.1 kardel * Revision 4.5 1998/08/16 19:01:51 kardel
610 1.1 kardel * debug information only compile for LIBDEBUG case
611 1.1 kardel *
612 1.1 kardel * Revision 4.4 1998/08/09 09:39:28 kardel
613 1.1 kardel * Release 4.0.73e2 reconcilation
614 1.1 kardel *
615 1.1 kardel * Revision 4.3 1998/06/13 11:56:19 kardel
616 1.1 kardel * disabled putbute() for the time being
617 1.1 kardel *
618 1.1 kardel * Revision 4.2 1998/06/12 15:16:58 kardel
619 1.1 kardel * ansi2knr compatibility
620 1.1 kardel *
621 1.1 kardel * Revision 4.1 1998/05/24 07:59:56 kardel
622 1.1 kardel * conditional debug support
623 1.1 kardel *
624 1.1 kardel * Revision 4.0 1998/04/10 19:46:29 kardel
625 1.1 kardel * Start 4.0 release version numbering
626 1.1 kardel *
627 1.1 kardel * Revision 1.1 1998/04/10 19:27:46 kardel
628 1.1 kardel * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
629 1.1 kardel *
630 1.1 kardel * Revision 1.1 1997/10/06 21:05:45 kardel
631 1.1 kardel * new parse structure
632 1.1 kardel *
633 1.1 kardel */
634