2 * /src/NTP/ntp4-dev/libntp/ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
4 * ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
6 * $Created: Sun Jul 13 09:12:02 1997 $
8 * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the author nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 #include "ntp_stdlib.h"
44 #include "ieee754io.h"
46 static unsigned char get_byte (unsigned char *, offsets_t, int *);
48 static void put_byte (unsigned char *, offsets_t, int *, unsigned char);
53 #include "lib_strbuf.h"
95 snprintf(buf, LIB_BUFLENGTH, "%c %s %s %s", sign ? '-' : '+',
115 for (i = 0; i < length; i++) {
116 snprintf(hex, sizeof(hex), "%02x", bufp[i]);
117 strlcat(buf, hex, LIB_BUFLENGTH);
134 val = *(bufp + offset[*fieldindex]);
137 printf("fetchieee754: getbyte(0x%08x, %d) = 0x%02x\n", (unsigned int)(bufp)+offset[*fieldindex], *fieldindex, val);
152 *(bufp + offsets[*fieldindex]) = val;
158 * make conversions to and from external IEEE754 formats and internal
163 unsigned char **buffpp,
169 unsigned char *bufp = *buffpp;
175 u_long mantissa_high;
176 u_long characteristic;
208 val = get_byte(bufp, offsets, &fieldindex); /* fetch sign byte & first part of characteristic */
210 sign = (val & 0x80) != 0;
211 characteristic = (val & 0x7F);
213 val = get_byte(bufp, offsets, &fieldindex); /* fetch rest of characteristic and start of mantissa */
218 characteristic <<= 1;
219 characteristic |= (val & 0x80) != 0; /* grab last characteristic bit */
223 mantissa_low = (val &0x7F) << 16;
224 mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
225 mantissa_low |= get_byte(bufp, offsets, &fieldindex);
229 characteristic <<= 4;
230 characteristic |= (val & 0xF0) >> 4; /* grab lower characteristic bits */
232 mantissa_high = (val & 0x0F) << 16;
233 mantissa_high |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
234 mantissa_high |= get_byte(bufp, offsets, &fieldindex);
236 mantissa_low = (u_long)get_byte(bufp, offsets, &fieldindex) << 24;
237 mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 16;
238 mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
239 mantissa_low |= get_byte(bufp, offsets, &fieldindex);
251 if (size == IEEE_SINGLE)
255 for (i = 0; i < length; i++)
257 *((unsigned char *)(&f)+i) = *(*buffpp + offsets[i]);
265 for (i = 0; i < length; i++)
267 *((unsigned char *)(&d)+i) = *(*buffpp + offsets[i]);
271 printf("fetchieee754: FP: %s -> %s -> %e(=%s)\n", fmt_hex(*buffpp, length),
272 fmt_flt(sign, mantissa_high, mantissa_low, characteristic),
273 d, fmt_hex((unsigned char *)&d, length));
277 *buffpp += fieldindex;
280 * detect funny numbers
282 if (characteristic == maxexp)
287 if (mantissa_low || mantissa_high)
299 return sign ? IEEE_NEGINFINITY : IEEE_POSINFINITY;
305 * collect real numbers
311 * check for overflows
313 exponent = characteristic - bias;
315 if (exponent > 31) /* sorry - hardcoded */
318 * overflow only in respect to NTP-FP representation
320 return sign ? IEEE_NEGOVERFLOW : IEEE_POSOVERFLOW;
324 int frac_offset; /* where the fraction starts */
326 frac_offset = mbits - exponent;
328 if (characteristic == 0)
331 * de-normalized or tiny number - fits only as 0
338 * adjust for implied 1
341 mantissa_high |= 1 << (mbits - 32);
343 mantissa_low |= 1 << mbits;
346 * take mantissa apart - if only all machine would support
347 * 64 bit operations 8-(
349 if (frac_offset > mbits)
351 lfpp->l_ui = 0; /* only fractional number */
352 frac_offset -= mbits + 1; /* will now contain right shift count - 1*/
355 lfpp->l_uf = mantissa_high << (63 - mbits);
356 lfpp->l_uf |= mantissa_low >> (mbits - 33);
357 lfpp->l_uf >>= frac_offset;
361 lfpp->l_uf = mantissa_low >> frac_offset;
366 if (frac_offset > 32)
369 * must split in high word
371 lfpp->l_ui = mantissa_high >> (frac_offset - 32);
372 lfpp->l_uf = (mantissa_high & ((1 << (frac_offset - 32)) - 1)) << (64 - frac_offset);
373 lfpp->l_uf |= mantissa_low >> (frac_offset - 32);
378 * must split in low word
380 lfpp->l_ui = mantissa_high << (32 - frac_offset);
381 lfpp->l_ui |= (mantissa_low >> frac_offset) & ((1 << (32 - frac_offset)) - 1);
382 lfpp->l_uf = (mantissa_low & ((1 << frac_offset) - 1)) << (32 - frac_offset);
402 unsigned char **bufpp,
413 /*unsigned int maxexp;*/
416 u_long mantissa_low = 0;
417 u_long mantissa_high = 0;
419 u_long characteristic = 0;
454 if (L_ISNEG(&outlfp))
468 if (L_ISZERO(&outlfp))
471 exponent = mantissa_high = mantissa_low = 0; /* true zero */
477 * find number of significant integer bits
483 while (mask && ((outlfp.l_ui & mask) == 0))
492 while (mask && ((outlfp.l_uf & mask) == 0))
505 mantissa_low = (outlfp.l_ui & ((1 << (msb - 32)) - 1)) << (mbits - (msb - 32));
506 mantissa_low |= outlfp.l_uf >> (mbits - (msb - 32));
510 mantissa_low = (outlfp.l_uf << (mbits - msb)) & ((1 << mbits) - 1);
517 mantissa_high = (outlfp.l_ui << (mbits - msb)) & ((1 << (mbits - 32)) - 1);
518 mantissa_high |= outlfp.l_uf >> (32 - (mbits - msb));
519 mantissa_low = (outlfp.l_ui & ((1 << (msb - mbits)) - 1)) << (32 - (msb - mbits));
520 mantissa_low |= outlfp.l_uf >> (msb - mbits);
524 mantissa_high = outlfp.l_uf << (mbits - 32 - msb);
525 mantissa_low = outlfp.l_uf << (mbits - 32);
531 characteristic = exponent + bias;
534 printf("FP: %s\n", fmt_flt(sign, mantissa_high, mantissa_low, characteristic));
541 #if defined(DEBUG) && defined(LIBDEBUG)
547 static offsets_t native_off = { 0, 1, 2, 3, 4, 5, 6, 7 };
554 if (sscanf(argv[1], "%lf", &f) != 1)
556 printf("cannot convert %s to a float\n", argv[1]);
561 printf("double: %s %s\n", fmt_blong(*(unsigned long *)&f, 32), fmt_blong(*(unsigned long *)((char *)(&f)+4), 32));
562 printf("fetch from %f = %d\n", f, fetch_ieee754((void *)&f_p, IEEE_DOUBLE, &fp, native_off));
563 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));
565 put_ieee754((void *)&f_p, IEEE_DOUBLE, &fp, native_off);
575 * Revision 4.12 2005/04/16 17:32:10 kardel
578 * Revision 4.11 2004/11/14 15:29:41 kardel
579 * support PPSAPI, upgrade Copyright to Berkeley style
581 * Revision 4.8 1999/02/21 12:17:36 kardel
582 * 4.91f reconcilation
584 * Revision 4.7 1999/02/21 11:26:03 kardel
585 * renamed index to fieldindex to avoid index() name clash
587 * Revision 4.6 1998/11/15 20:27:52 kardel
588 * Release 4.0.73e13 reconcilation
590 * Revision 4.5 1998/08/16 19:01:51 kardel
591 * debug information only compile for LIBDEBUG case
593 * Revision 4.4 1998/08/09 09:39:28 kardel
594 * Release 4.0.73e2 reconcilation
596 * Revision 4.3 1998/06/13 11:56:19 kardel
597 * disabled putbute() for the time being
599 * Revision 4.2 1998/06/12 15:16:58 kardel
600 * ansi2knr compatibility
602 * Revision 4.1 1998/05/24 07:59:56 kardel
603 * conditional debug support
605 * Revision 4.0 1998/04/10 19:46:29 kardel
606 * Start 4.0 release version numbering
608 * Revision 1.1 1998/04/10 19:27:46 kardel
609 * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
611 * Revision 1.1 1997/10/06 21:05:45 kardel
612 * new parse structure