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