4 * /src/NTP/ntp4-dev/libntp/ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
6 * ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
8 * Created: Sun Jul 13 09:12:02 1997
10 * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the author nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 #include "ntp_stdlib.h"
46 #include "ieee754io.h"
48 static unsigned char get_byte
P((unsigned char *, offsets_t
, int *));
50 static void put_byte
P((unsigned char *, offsets_t
, int *, unsigned char));
55 #include "lib_strbuf.h"
97 sprintf(buf
, "%c %s %s %s", sign
? '-' : '+',
114 for (i
= 0; i
< length
; i
++)
116 sprintf(buf
+i
*2, "%02x", bufp
[i
]);
132 val
= *(bufp
+ offset
[*fieldindex
]);
135 printf("fetchieee754: getbyte(0x%08x, %d) = 0x%02x\n", (unsigned int)(bufp
)+offset
[*fieldindex
], *fieldindex
, val
);
150 *(bufp
+ offsets
[*fieldindex
]) = val
;
156 * make conversions to and from external IEEE754 formats and internal
161 unsigned char **buffpp
,
167 unsigned char *bufp
= *buffpp
;
173 u_long mantissa_high
;
174 u_long characteristic
;
206 val
= get_byte(bufp
, offsets
, &fieldindex
); /* fetch sign byte & first part of characteristic */
208 sign
= (val
& 0x80) != 0;
209 characteristic
= (val
& 0x7F);
211 val
= get_byte(bufp
, offsets
, &fieldindex
); /* fetch rest of characteristic and start of mantissa */
216 characteristic
<<= 1;
217 characteristic
|= (val
& 0x80) != 0; /* grab last characteristic bit */
221 mantissa_low
= (val
&0x7F) << 16;
222 mantissa_low
|= get_byte(bufp
, offsets
, &fieldindex
) << 8;
223 mantissa_low
|= get_byte(bufp
, offsets
, &fieldindex
);
227 characteristic
<<= 4;
228 characteristic
|= (val
& 0xF0) >> 4; /* grab lower characteristic bits */
230 mantissa_high
= (val
& 0x0F) << 16;
231 mantissa_high
|= get_byte(bufp
, offsets
, &fieldindex
) << 8;
232 mantissa_high
|= get_byte(bufp
, offsets
, &fieldindex
);
234 mantissa_low
= get_byte(bufp
, offsets
, &fieldindex
) << 24;
235 mantissa_low
|= get_byte(bufp
, offsets
, &fieldindex
) << 16;
236 mantissa_low
|= get_byte(bufp
, offsets
, &fieldindex
) << 8;
237 mantissa_low
|= get_byte(bufp
, offsets
, &fieldindex
);
249 if (size
== IEEE_SINGLE
)
253 for (i
= 0; i
< length
; i
++)
255 *((unsigned char *)(&f
)+i
) = *(*buffpp
+ offsets
[i
]);
263 for (i
= 0; i
< length
; i
++)
265 *((unsigned char *)(&d
)+i
) = *(*buffpp
+ offsets
[i
]);
269 printf("fetchieee754: FP: %s -> %s -> %e(=%s)\n", fmt_hex(*buffpp
, length
),
270 fmt_flt(sign
, mantissa_high
, mantissa_low
, characteristic
),
271 d
, fmt_hex((unsigned char *)&d
, length
));
275 *buffpp
+= fieldindex
;
278 * detect funny numbers
280 if (characteristic
== maxexp
)
285 if (mantissa_low
|| mantissa_high
)
297 return sign
? IEEE_NEGINFINITY
: IEEE_POSINFINITY
;
303 * collect real numbers
309 * check for overflows
311 exponent
= characteristic
- bias
;
313 if (exponent
> 31) /* sorry - hardcoded */
316 * overflow only in respect to NTP-FP representation
318 return sign
? IEEE_NEGOVERFLOW
: IEEE_POSOVERFLOW
;
322 int frac_offset
; /* where the fraction starts */
324 frac_offset
= mbits
- exponent
;
326 if (characteristic
== 0)
329 * de-normalized or tiny number - fits only as 0
336 * adjust for implied 1
339 mantissa_high
|= 1 << (mbits
- 32);
341 mantissa_low
|= 1 << mbits
;
344 * take mantissa apart - if only all machine would support
345 * 64 bit operations 8-(
347 if (frac_offset
> mbits
)
349 lfpp
->l_ui
= 0; /* only fractional number */
350 frac_offset
-= mbits
+ 1; /* will now contain right shift count - 1*/
353 lfpp
->l_uf
= mantissa_high
<< (63 - mbits
);
354 lfpp
->l_uf
|= mantissa_low
>> (mbits
- 33);
355 lfpp
->l_uf
>>= frac_offset
;
359 lfpp
->l_uf
= mantissa_low
>> frac_offset
;
364 if (frac_offset
> 32)
367 * must split in high word
369 lfpp
->l_ui
= mantissa_high
>> (frac_offset
- 32);
370 lfpp
->l_uf
= (mantissa_high
& ((1 << (frac_offset
- 32)) - 1)) << (64 - frac_offset
);
371 lfpp
->l_uf
|= mantissa_low
>> (frac_offset
- 32);
376 * must split in low word
378 lfpp
->l_ui
= mantissa_high
<< (32 - frac_offset
);
379 lfpp
->l_ui
|= (mantissa_low
>> frac_offset
) & ((1 << (32 - frac_offset
)) - 1);
380 lfpp
->l_uf
= (mantissa_low
& ((1 << frac_offset
) - 1)) << (32 - frac_offset
);
400 unsigned char **bufpp
,
411 /*unsigned int maxexp;*/
414 u_long mantissa_low
= 0;
415 u_long mantissa_high
= 0;
417 u_long characteristic
= 0;
452 if (L_ISNEG(&outlfp
))
466 if (L_ISZERO(&outlfp
))
469 exponent
= mantissa_high
= mantissa_low
= 0; /* true zero */
475 * find number of significant integer bits
481 while (mask
&& ((outlfp
.l_ui
& mask
) == 0))
490 while (mask
&& ((outlfp
.l_uf
& mask
) == 0))
503 mantissa_low
= (outlfp
.l_ui
& ((1 << (msb
- 32)) - 1)) << (mbits
- (msb
- 32));
504 mantissa_low
|= outlfp
.l_uf
>> (mbits
- (msb
- 32));
508 mantissa_low
= (outlfp
.l_uf
<< (mbits
- msb
)) & ((1 << mbits
) - 1);
515 mantissa_high
= (outlfp
.l_ui
<< (mbits
- msb
)) & ((1 << (mbits
- 32)) - 1);
516 mantissa_high
|= outlfp
.l_uf
>> (32 - (mbits
- msb
));
517 mantissa_low
= (outlfp
.l_ui
& ((1 << (msb
- mbits
)) - 1)) << (32 - (msb
- mbits
));
518 mantissa_low
|= outlfp
.l_uf
>> (msb
- mbits
);
522 mantissa_high
= outlfp
.l_uf
<< (mbits
- 32 - msb
);
523 mantissa_low
= outlfp
.l_uf
<< (mbits
- 32);
529 characteristic
= exponent
+ bias
;
532 printf("FP: %s\n", fmt_flt(sign
, mantissa_high
, mantissa_low
, characteristic
));
539 #if defined(DEBUG) && defined(LIBDEBUG)
545 static offsets_t native_off
= { 0, 1, 2, 3, 4, 5, 6, 7 };
552 if (sscanf(argv
[1], "%lf", &f
) != 1)
554 printf("cannot convert %s to a float\n", argv
[1]);
559 printf("double: %s %s\n", fmt_blong(*(unsigned long *)&f
, 32), fmt_blong(*(unsigned long *)((char *)(&f
)+4), 32));
560 printf("fetch from %f = %d\n", f
, fetch_ieee754((void *)&f_p
, IEEE_DOUBLE
, &fp
, native_off
));
561 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));
563 put_ieee754((void *)&f_p
, IEEE_DOUBLE
, &fp
, native_off
);
573 * Revision 4.12 2005/04/16 17:32:10 kardel
576 * Revision 4.11 2004/11/14 15:29:41 kardel
577 * support PPSAPI, upgrade Copyright to Berkeley style
579 * Revision 4.8 1999/02/21 12:17:36 kardel
580 * 4.91f reconcilation
582 * Revision 4.7 1999/02/21 11:26:03 kardel
583 * renamed index to fieldindex to avoid index() name clash
585 * Revision 4.6 1998/11/15 20:27:52 kardel
586 * Release 4.0.73e13 reconcilation
588 * Revision 4.5 1998/08/16 19:01:51 kardel
589 * debug information only compile for LIBDEBUG case
591 * Revision 4.4 1998/08/09 09:39:28 kardel
592 * Release 4.0.73e2 reconcilation
594 * Revision 4.3 1998/06/13 11:56:19 kardel
595 * disabled putbute() for the time being
597 * Revision 4.2 1998/06/12 15:16:58 kardel
598 * ansi2knr compatibility
600 * Revision 4.1 1998/05/24 07:59:56 kardel
601 * conditional debug support
603 * Revision 4.0 1998/04/10 19:46:29 kardel
604 * Start 4.0 release version numbering
606 * Revision 1.1 1998/04/10 19:27:46 kardel
607 * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
609 * Revision 1.1 1997/10/06 21:05:45 kardel
610 * new parse structure