Home | History | Annotate | Line # | Download | only in libparse
ieee754io.c revision 1.1
      1  1.1  kardel /*	$NetBSD: ieee754io.c,v 1.1 2009/12/13 16:55:22 kardel 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.1  kardel  * 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 #include "lib_strbuf.h"
     56  1.1  kardel 
     57  1.1  kardel static char *
     58  1.1  kardel fmt_blong(
     59  1.1  kardel 	  unsigned long val,
     60  1.1  kardel 	  int cnt
     61  1.1  kardel 	  )
     62  1.1  kardel {
     63  1.1  kardel   char *buf, *s;
     64  1.1  kardel   int i = cnt;
     65  1.1  kardel 
     66  1.1  kardel   val <<= 32 - cnt;
     67  1.1  kardel   LIB_GETBUF(buf);
     68  1.1  kardel   s = buf;
     69  1.1  kardel 
     70  1.1  kardel   while (i--)
     71  1.1  kardel     {
     72  1.1  kardel       if (val & 0x80000000)
     73  1.1  kardel 	{
     74  1.1  kardel 	  *s++ = '1';
     75  1.1  kardel 	}
     76  1.1  kardel       else
     77  1.1  kardel 	{
     78  1.1  kardel 	  *s++ = '0';
     79  1.1  kardel 	}
     80  1.1  kardel       val <<= 1;
     81  1.1  kardel     }
     82  1.1  kardel   *s = '\0';
     83  1.1  kardel   return buf;
     84  1.1  kardel }
     85  1.1  kardel 
     86  1.1  kardel static char *
     87  1.1  kardel fmt_flt(
     88  1.1  kardel 	unsigned int sign,
     89  1.1  kardel 	unsigned long mh,
     90  1.1  kardel 	unsigned long ml,
     91  1.1  kardel 	unsigned long ch
     92  1.1  kardel 	)
     93  1.1  kardel {
     94  1.1  kardel   char *buf;
     95  1.1  kardel 
     96  1.1  kardel   LIB_GETBUF(buf);
     97  1.1  kardel   sprintf(buf, "%c %s %s %s", sign ? '-' : '+',
     98  1.1  kardel 	  fmt_blong(ch, 11),
     99  1.1  kardel 	  fmt_blong(mh, 20),
    100  1.1  kardel 	  fmt_blong(ml, 32));
    101  1.1  kardel   return buf;
    102  1.1  kardel }
    103  1.1  kardel 
    104  1.1  kardel static char *
    105  1.1  kardel fmt_hex(
    106  1.1  kardel 	unsigned char *bufp,
    107  1.1  kardel 	int length
    108  1.1  kardel 	)
    109  1.1  kardel {
    110  1.1  kardel   char *buf;
    111  1.1  kardel   int i;
    112  1.1  kardel 
    113  1.1  kardel   LIB_GETBUF(buf);
    114  1.1  kardel   for (i = 0; i < length; i++)
    115  1.1  kardel     {
    116  1.1  kardel       sprintf(buf+i*2, "%02x", bufp[i]);
    117  1.1  kardel     }
    118  1.1  kardel   return buf;
    119  1.1  kardel }
    120  1.1  kardel 
    121  1.1  kardel #endif
    122  1.1  kardel 
    123  1.1  kardel static unsigned char
    124  1.1  kardel get_byte(
    125  1.1  kardel 	 unsigned char *bufp,
    126  1.1  kardel 	 offsets_t offset,
    127  1.1  kardel 	 int *fieldindex
    128  1.1  kardel 	 )
    129  1.1  kardel {
    130  1.1  kardel   unsigned char val;
    131  1.1  kardel 
    132  1.1  kardel   val     = *(bufp + offset[*fieldindex]);
    133  1.1  kardel #ifdef LIBDEBUG
    134  1.1  kardel   if (debug > 4)
    135  1.1  kardel     printf("fetchieee754: getbyte(0x%08x, %d) = 0x%02x\n", (unsigned int)(bufp)+offset[*fieldindex], *fieldindex, val);
    136  1.1  kardel #endif
    137  1.1  kardel   (*fieldindex)++;
    138  1.1  kardel   return val;
    139  1.1  kardel }
    140  1.1  kardel 
    141  1.1  kardel #ifdef __not_yet__
    142  1.1  kardel static void
    143  1.1  kardel put_byte(
    144  1.1  kardel 	 unsigned char *bufp,
    145  1.1  kardel 	 offsets_t offsets,
    146  1.1  kardel 	 int *fieldindex,
    147  1.1  kardel 	 unsigned char val
    148  1.1  kardel 	 )
    149  1.1  kardel {
    150  1.1  kardel   *(bufp + offsets[*fieldindex]) = val;
    151  1.1  kardel   (*fieldindex)++;
    152  1.1  kardel }
    153  1.1  kardel #endif
    154  1.1  kardel 
    155  1.1  kardel /*
    156  1.1  kardel  * make conversions to and from external IEEE754 formats and internal
    157  1.1  kardel  * NTP FP format.
    158  1.1  kardel  */
    159  1.1  kardel int
    160  1.1  kardel fetch_ieee754(
    161  1.1  kardel 	      unsigned char **buffpp,
    162  1.1  kardel 	      int size,
    163  1.1  kardel 	      l_fp *lfpp,
    164  1.1  kardel 	      offsets_t offsets
    165  1.1  kardel 	      )
    166  1.1  kardel {
    167  1.1  kardel   unsigned char *bufp = *buffpp;
    168  1.1  kardel   unsigned int sign;
    169  1.1  kardel   unsigned int bias;
    170  1.1  kardel   unsigned int maxexp;
    171  1.1  kardel   int mbits;
    172  1.1  kardel   u_long mantissa_low;
    173  1.1  kardel   u_long mantissa_high;
    174  1.1  kardel   u_long characteristic;
    175  1.1  kardel   long exponent;
    176  1.1  kardel #ifdef LIBDEBUG
    177  1.1  kardel   int length;
    178  1.1  kardel #endif
    179  1.1  kardel   unsigned char val;
    180  1.1  kardel   int fieldindex = 0;
    181  1.1  kardel 
    182  1.1  kardel   switch (size)
    183  1.1  kardel     {
    184  1.1  kardel     case IEEE_DOUBLE:
    185  1.1  kardel #ifdef LIBDEBUG
    186  1.1  kardel       length = 8;
    187  1.1  kardel #endif
    188  1.1  kardel       mbits  = 52;
    189  1.1  kardel       bias   = 1023;
    190  1.1  kardel       maxexp = 2047;
    191  1.1  kardel       break;
    192  1.1  kardel 
    193  1.1  kardel     case IEEE_SINGLE:
    194  1.1  kardel #ifdef LIBDEBUG
    195  1.1  kardel       length = 4;
    196  1.1  kardel #endif
    197  1.1  kardel       mbits  = 23;
    198  1.1  kardel       bias   = 127;
    199  1.1  kardel       maxexp = 255;
    200  1.1  kardel       break;
    201  1.1  kardel 
    202  1.1  kardel     default:
    203  1.1  kardel       return IEEE_BADCALL;
    204  1.1  kardel     }
    205  1.1  kardel 
    206  1.1  kardel   val = get_byte(bufp, offsets, &fieldindex); /* fetch sign byte & first part of characteristic */
    207  1.1  kardel 
    208  1.1  kardel   sign     = (val & 0x80) != 0;
    209  1.1  kardel   characteristic = (val & 0x7F);
    210  1.1  kardel 
    211  1.1  kardel   val = get_byte(bufp, offsets, &fieldindex); /* fetch rest of characteristic and start of mantissa */
    212  1.1  kardel 
    213  1.1  kardel   switch (size)
    214  1.1  kardel     {
    215  1.1  kardel     case IEEE_SINGLE:
    216  1.1  kardel       characteristic <<= 1;
    217  1.1  kardel       characteristic  |= (val & 0x80) != 0; /* grab last characteristic bit */
    218  1.1  kardel 
    219  1.1  kardel       mantissa_high  = 0;
    220  1.1  kardel 
    221  1.1  kardel       mantissa_low   = (val &0x7F) << 16;
    222  1.1  kardel       mantissa_low  |= get_byte(bufp, offsets, &fieldindex) << 8;
    223  1.1  kardel       mantissa_low  |= get_byte(bufp, offsets, &fieldindex);
    224  1.1  kardel       break;
    225  1.1  kardel 
    226  1.1  kardel     case IEEE_DOUBLE:
    227  1.1  kardel       characteristic <<= 4;
    228  1.1  kardel       characteristic  |= (val & 0xF0) >> 4; /* grab lower characteristic bits */
    229  1.1  kardel 
    230  1.1  kardel       mantissa_high  = (val & 0x0F) << 16;
    231  1.1  kardel       mantissa_high |= get_byte(bufp, offsets, &fieldindex) << 8;
    232  1.1  kardel       mantissa_high |= get_byte(bufp, offsets, &fieldindex);
    233  1.1  kardel 
    234  1.1  kardel       mantissa_low   = get_byte(bufp, offsets, &fieldindex) << 24;
    235  1.1  kardel       mantissa_low  |= get_byte(bufp, offsets, &fieldindex) << 16;
    236  1.1  kardel       mantissa_low  |= get_byte(bufp, offsets, &fieldindex) << 8;
    237  1.1  kardel       mantissa_low  |= get_byte(bufp, offsets, &fieldindex);
    238  1.1  kardel       break;
    239  1.1  kardel 
    240  1.1  kardel     default:
    241  1.1  kardel       return IEEE_BADCALL;
    242  1.1  kardel     }
    243  1.1  kardel #ifdef LIBDEBUG
    244  1.1  kardel   if (debug > 4)
    245  1.1  kardel   {
    246  1.1  kardel     double d;
    247  1.1  kardel     float f;
    248  1.1  kardel 
    249  1.1  kardel     if (size == IEEE_SINGLE)
    250  1.1  kardel       {
    251  1.1  kardel 	int i;
    252  1.1  kardel 
    253  1.1  kardel 	for (i = 0; i < length; i++)
    254  1.1  kardel 	  {
    255  1.1  kardel 	    *((unsigned char *)(&f)+i) = *(*buffpp + offsets[i]);
    256  1.1  kardel 	  }
    257  1.1  kardel 	d = f;
    258  1.1  kardel       }
    259  1.1  kardel     else
    260  1.1  kardel       {
    261  1.1  kardel 	int i;
    262  1.1  kardel 
    263  1.1  kardel 	for (i = 0; i < length; i++)
    264  1.1  kardel 	  {
    265  1.1  kardel 	    *((unsigned char *)(&d)+i) = *(*buffpp + offsets[i]);
    266  1.1  kardel 	  }
    267  1.1  kardel       }
    268  1.1  kardel 
    269  1.1  kardel     printf("fetchieee754: FP: %s -> %s -> %e(=%s)\n", fmt_hex(*buffpp, length),
    270  1.1  kardel 	   fmt_flt(sign, mantissa_high, mantissa_low, characteristic),
    271  1.1  kardel 	   d, fmt_hex((unsigned char *)&d, length));
    272  1.1  kardel   }
    273  1.1  kardel #endif
    274  1.1  kardel 
    275  1.1  kardel   *buffpp += fieldindex;
    276  1.1  kardel 
    277  1.1  kardel   /*
    278  1.1  kardel    * detect funny numbers
    279  1.1  kardel    */
    280  1.1  kardel   if (characteristic == maxexp)
    281  1.1  kardel     {
    282  1.1  kardel       /*
    283  1.1  kardel        * NaN or Infinity
    284  1.1  kardel        */
    285  1.1  kardel       if (mantissa_low || mantissa_high)
    286  1.1  kardel 	{
    287  1.1  kardel 	  /*
    288  1.1  kardel 	   * NaN
    289  1.1  kardel 	   */
    290  1.1  kardel 	  return IEEE_NAN;
    291  1.1  kardel 	}
    292  1.1  kardel       else
    293  1.1  kardel 	{
    294  1.1  kardel 	  /*
    295  1.1  kardel 	   * +Inf or -Inf
    296  1.1  kardel 	   */
    297  1.1  kardel 	  return sign ? IEEE_NEGINFINITY : IEEE_POSINFINITY;
    298  1.1  kardel 	}
    299  1.1  kardel     }
    300  1.1  kardel   else
    301  1.1  kardel     {
    302  1.1  kardel       /*
    303  1.1  kardel        * collect real numbers
    304  1.1  kardel        */
    305  1.1  kardel 
    306  1.1  kardel       L_CLR(lfpp);
    307  1.1  kardel 
    308  1.1  kardel       /*
    309  1.1  kardel        * check for overflows
    310  1.1  kardel        */
    311  1.1  kardel       exponent = characteristic - bias;
    312  1.1  kardel 
    313  1.1  kardel       if (exponent > 31)	/* sorry - hardcoded */
    314  1.1  kardel 	{
    315  1.1  kardel 	  /*
    316  1.1  kardel 	   * overflow only in respect to NTP-FP representation
    317  1.1  kardel 	   */
    318  1.1  kardel 	  return sign ? IEEE_NEGOVERFLOW : IEEE_POSOVERFLOW;
    319  1.1  kardel 	}
    320  1.1  kardel       else
    321  1.1  kardel 	{
    322  1.1  kardel 	  int frac_offset;	/* where the fraction starts */
    323  1.1  kardel 
    324  1.1  kardel 	  frac_offset = mbits - exponent;
    325  1.1  kardel 
    326  1.1  kardel 	  if (characteristic == 0)
    327  1.1  kardel 	    {
    328  1.1  kardel 	      /*
    329  1.1  kardel 	       * de-normalized or tiny number - fits only as 0
    330  1.1  kardel 	       */
    331  1.1  kardel 	      return IEEE_OK;
    332  1.1  kardel 	    }
    333  1.1  kardel 	  else
    334  1.1  kardel 	    {
    335  1.1  kardel 	      /*
    336  1.1  kardel 	       * adjust for implied 1
    337  1.1  kardel 	       */
    338  1.1  kardel 	      if (mbits > 31)
    339  1.1  kardel 		mantissa_high |= 1 << (mbits - 32);
    340  1.1  kardel 	      else
    341  1.1  kardel 		mantissa_low  |= 1 << mbits;
    342  1.1  kardel 
    343  1.1  kardel 	      /*
    344  1.1  kardel 	       * take mantissa apart - if only all machine would support
    345  1.1  kardel 	       * 64 bit operations 8-(
    346  1.1  kardel 	       */
    347  1.1  kardel 	      if (frac_offset > mbits)
    348  1.1  kardel 		{
    349  1.1  kardel 		  lfpp->l_ui = 0; /* only fractional number */
    350  1.1  kardel 		  frac_offset -= mbits + 1; /* will now contain right shift count - 1*/
    351  1.1  kardel 		  if (mbits > 31)
    352  1.1  kardel 		    {
    353  1.1  kardel 		      lfpp->l_uf   = mantissa_high << (63 - mbits);
    354  1.1  kardel 		      lfpp->l_uf  |= mantissa_low  >> (mbits - 33);
    355  1.1  kardel 		      lfpp->l_uf >>= frac_offset;
    356  1.1  kardel 		    }
    357  1.1  kardel 		  else
    358  1.1  kardel 		    {
    359  1.1  kardel 		      lfpp->l_uf = mantissa_low >> frac_offset;
    360  1.1  kardel 		    }
    361  1.1  kardel 		}
    362  1.1  kardel 	      else
    363  1.1  kardel 		{
    364  1.1  kardel 		  if (frac_offset > 32)
    365  1.1  kardel 		    {
    366  1.1  kardel 		      /*
    367  1.1  kardel 		       * must split in high word
    368  1.1  kardel 		       */
    369  1.1  kardel 		      lfpp->l_ui  =  mantissa_high >> (frac_offset - 32);
    370  1.1  kardel 		      lfpp->l_uf  = (mantissa_high & ((1 << (frac_offset - 32)) - 1)) << (64 - frac_offset);
    371  1.1  kardel 		      lfpp->l_uf |=  mantissa_low  >> (frac_offset - 32);
    372  1.1  kardel 		    }
    373  1.1  kardel 		  else
    374  1.1  kardel 		    {
    375  1.1  kardel 		      /*
    376  1.1  kardel 		       * must split in low word
    377  1.1  kardel 		       */
    378  1.1  kardel 		      lfpp->l_ui  =  mantissa_high << (32 - frac_offset);
    379  1.1  kardel 		      lfpp->l_ui |= (mantissa_low >> frac_offset) & ((1 << (32 - frac_offset)) - 1);
    380  1.1  kardel 		      lfpp->l_uf  = (mantissa_low & ((1 << frac_offset) - 1)) << (32 - frac_offset);
    381  1.1  kardel 		    }
    382  1.1  kardel 		}
    383  1.1  kardel 
    384  1.1  kardel 	      /*
    385  1.1  kardel 	       * adjust for sign
    386  1.1  kardel 	       */
    387  1.1  kardel 	      if (sign)
    388  1.1  kardel 		{
    389  1.1  kardel 		  L_NEG(lfpp);
    390  1.1  kardel 		}
    391  1.1  kardel 
    392  1.1  kardel 	      return IEEE_OK;
    393  1.1  kardel 	    }
    394  1.1  kardel 	}
    395  1.1  kardel     }
    396  1.1  kardel }
    397  1.1  kardel 
    398  1.1  kardel int
    399  1.1  kardel put_ieee754(
    400  1.1  kardel 	    unsigned char **bufpp,
    401  1.1  kardel 	    int size,
    402  1.1  kardel 	    l_fp *lfpp,
    403  1.1  kardel 	    offsets_t offsets
    404  1.1  kardel 	    )
    405  1.1  kardel {
    406  1.1  kardel   l_fp outlfp;
    407  1.1  kardel #ifdef LIBDEBUG
    408  1.1  kardel   unsigned int sign;
    409  1.1  kardel   unsigned int bias;
    410  1.1  kardel #endif
    411  1.1  kardel /*unsigned int maxexp;*/
    412  1.1  kardel   int mbits;
    413  1.1  kardel   int msb;
    414  1.1  kardel   u_long mantissa_low = 0;
    415  1.1  kardel   u_long mantissa_high = 0;
    416  1.1  kardel #ifdef LIBDEBUG
    417  1.1  kardel   u_long characteristic = 0;
    418  1.1  kardel   long exponent;
    419  1.1  kardel #endif
    420  1.1  kardel /*int length;*/
    421  1.1  kardel   unsigned long mask;
    422  1.1  kardel 
    423  1.1  kardel   outlfp = *lfpp;
    424  1.1  kardel 
    425  1.1  kardel   switch (size)
    426  1.1  kardel     {
    427  1.1  kardel     case IEEE_DOUBLE:
    428  1.1  kardel     /*length = 8;*/
    429  1.1  kardel       mbits  = 52;
    430  1.1  kardel #ifdef LIBDEBUG
    431  1.1  kardel       bias   = 1023;
    432  1.1  kardel #endif
    433  1.1  kardel     /*maxexp = 2047;*/
    434  1.1  kardel       break;
    435  1.1  kardel 
    436  1.1  kardel     case IEEE_SINGLE:
    437  1.1  kardel     /*length = 4;*/
    438  1.1  kardel       mbits  = 23;
    439  1.1  kardel #ifdef LIBDEBUG
    440  1.1  kardel       bias   = 127;
    441  1.1  kardel #endif
    442  1.1  kardel     /*maxexp = 255;*/
    443  1.1  kardel       break;
    444  1.1  kardel 
    445  1.1  kardel     default:
    446  1.1  kardel       return IEEE_BADCALL;
    447  1.1  kardel     }
    448  1.1  kardel 
    449  1.1  kardel   /*
    450  1.1  kardel    * find sign
    451  1.1  kardel    */
    452  1.1  kardel   if (L_ISNEG(&outlfp))
    453  1.1  kardel     {
    454  1.1  kardel       L_NEG(&outlfp);
    455  1.1  kardel #ifdef LIBDEBUG
    456  1.1  kardel       sign = 1;
    457  1.1  kardel #endif
    458  1.1  kardel     }
    459  1.1  kardel   else
    460  1.1  kardel     {
    461  1.1  kardel #ifdef LIBDEBUG
    462  1.1  kardel       sign = 0;
    463  1.1  kardel #endif
    464  1.1  kardel     }
    465  1.1  kardel 
    466  1.1  kardel   if (L_ISZERO(&outlfp))
    467  1.1  kardel     {
    468  1.1  kardel #ifdef LIBDEBUG
    469  1.1  kardel       exponent = mantissa_high = mantissa_low = 0; /* true zero */
    470  1.1  kardel #endif
    471  1.1  kardel     }
    472  1.1  kardel   else
    473  1.1  kardel     {
    474  1.1  kardel       /*
    475  1.1  kardel        * find number of significant integer bits
    476  1.1  kardel        */
    477  1.1  kardel       mask = 0x80000000;
    478  1.1  kardel       if (outlfp.l_ui)
    479  1.1  kardel 	{
    480  1.1  kardel 	  msb = 63;
    481  1.1  kardel 	  while (mask && ((outlfp.l_ui & mask) == 0))
    482  1.1  kardel 	    {
    483  1.1  kardel 	      mask >>= 1;
    484  1.1  kardel 	      msb--;
    485  1.1  kardel 	    }
    486  1.1  kardel 	}
    487  1.1  kardel       else
    488  1.1  kardel 	{
    489  1.1  kardel 	  msb = 31;
    490  1.1  kardel 	  while (mask && ((outlfp.l_uf & mask) == 0))
    491  1.1  kardel 	    {
    492  1.1  kardel 	      mask >>= 1;
    493  1.1  kardel 	      msb--;
    494  1.1  kardel 	    }
    495  1.1  kardel 	}
    496  1.1  kardel 
    497  1.1  kardel       switch (size)
    498  1.1  kardel 	{
    499  1.1  kardel 	case IEEE_SINGLE:
    500  1.1  kardel 	  mantissa_high = 0;
    501  1.1  kardel 	  if (msb >= 32)
    502  1.1  kardel 	    {
    503  1.1  kardel 	      mantissa_low  = (outlfp.l_ui & ((1 << (msb - 32)) - 1)) << (mbits - (msb - 32));
    504  1.1  kardel 	      mantissa_low |=  outlfp.l_uf >> (mbits - (msb - 32));
    505  1.1  kardel 	    }
    506  1.1  kardel 	  else
    507  1.1  kardel 	    {
    508  1.1  kardel 	      mantissa_low  = (outlfp.l_uf << (mbits - msb)) & ((1 << mbits) - 1);
    509  1.1  kardel 	    }
    510  1.1  kardel 	  break;
    511  1.1  kardel 
    512  1.1  kardel 	case IEEE_DOUBLE:
    513  1.1  kardel 	  if (msb >= 32)
    514  1.1  kardel 	    {
    515  1.1  kardel 	      mantissa_high  = (outlfp.l_ui << (mbits - msb)) & ((1 << (mbits - 32)) - 1);
    516  1.1  kardel 	      mantissa_high |=  outlfp.l_uf >> (32 - (mbits - msb));
    517  1.1  kardel 	      mantissa_low   = (outlfp.l_ui & ((1 << (msb - mbits)) - 1)) << (32 - (msb - mbits));
    518  1.1  kardel 	      mantissa_low  |=  outlfp.l_uf >> (msb - mbits);
    519  1.1  kardel 	    }
    520  1.1  kardel 	  else
    521  1.1  kardel 	    {
    522  1.1  kardel 	      mantissa_high  = outlfp.l_uf << (mbits - 32 - msb);
    523  1.1  kardel 	      mantissa_low   = outlfp.l_uf << (mbits - 32);
    524  1.1  kardel 	    }
    525  1.1  kardel 	}
    526  1.1  kardel 
    527  1.1  kardel #ifdef LIBDEBUG
    528  1.1  kardel       exponent = msb - 32;
    529  1.1  kardel       characteristic = exponent + bias;
    530  1.1  kardel 
    531  1.1  kardel       if (debug > 4)
    532  1.1  kardel 	printf("FP: %s\n", fmt_flt(sign, mantissa_high, mantissa_low, characteristic));
    533  1.1  kardel #endif
    534  1.1  kardel     }
    535  1.1  kardel   return IEEE_OK;
    536  1.1  kardel }
    537  1.1  kardel 
    538  1.1  kardel 
    539  1.1  kardel #if defined(DEBUG) && defined(LIBDEBUG)
    540  1.1  kardel int main(
    541  1.1  kardel 	 int argc,
    542  1.1  kardel 	 char **argv
    543  1.1  kardel 	 )
    544  1.1  kardel {
    545  1.1  kardel   static offsets_t native_off = { 0, 1, 2, 3, 4, 5, 6, 7 };
    546  1.1  kardel   double f = 1.0;
    547  1.1  kardel   double *f_p = &f;
    548  1.1  kardel   l_fp fp;
    549  1.1  kardel 
    550  1.1  kardel   if (argc == 2)
    551  1.1  kardel     {
    552  1.1  kardel       if (sscanf(argv[1], "%lf", &f) != 1)
    553  1.1  kardel 	{
    554  1.1  kardel 	  printf("cannot convert %s to a float\n", argv[1]);
    555  1.1  kardel 	  return 1;
    556  1.1  kardel 	}
    557  1.1  kardel     }
    558  1.1  kardel 
    559  1.1  kardel   printf("double: %s %s\n", fmt_blong(*(unsigned long *)&f, 32), fmt_blong(*(unsigned long *)((char *)(&f)+4), 32));
    560  1.1  kardel   printf("fetch from %f = %d\n", f, fetch_ieee754((void *)&f_p, IEEE_DOUBLE, &fp, native_off));
    561  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));
    562  1.1  kardel   f_p = &f;
    563  1.1  kardel   put_ieee754((void *)&f_p, IEEE_DOUBLE, &fp, native_off);
    564  1.1  kardel 
    565  1.1  kardel   return 0;
    566  1.1  kardel }
    567  1.1  kardel 
    568  1.1  kardel #endif
    569  1.1  kardel /*
    570  1.1  kardel  * History:
    571  1.1  kardel  *
    572  1.1  kardel  * ieee754io.c,v
    573  1.1  kardel  * Revision 4.12  2005/04/16 17:32:10  kardel
    574  1.1  kardel  * update copyright
    575  1.1  kardel  *
    576  1.1  kardel  * Revision 4.11  2004/11/14 15:29:41  kardel
    577  1.1  kardel  * support PPSAPI, upgrade Copyright to Berkeley style
    578  1.1  kardel  *
    579  1.1  kardel  * Revision 4.8  1999/02/21 12:17:36  kardel
    580  1.1  kardel  * 4.91f reconcilation
    581  1.1  kardel  *
    582  1.1  kardel  * Revision 4.7  1999/02/21 11:26:03  kardel
    583  1.1  kardel  * renamed index to fieldindex to avoid index() name clash
    584  1.1  kardel  *
    585  1.1  kardel  * Revision 4.6  1998/11/15 20:27:52  kardel
    586  1.1  kardel  * Release 4.0.73e13 reconcilation
    587  1.1  kardel  *
    588  1.1  kardel  * Revision 4.5  1998/08/16 19:01:51  kardel
    589  1.1  kardel  * debug information only compile for LIBDEBUG case
    590  1.1  kardel  *
    591  1.1  kardel  * Revision 4.4  1998/08/09 09:39:28  kardel
    592  1.1  kardel  * Release 4.0.73e2 reconcilation
    593  1.1  kardel  *
    594  1.1  kardel  * Revision 4.3  1998/06/13 11:56:19  kardel
    595  1.1  kardel  * disabled putbute() for the time being
    596  1.1  kardel  *
    597  1.1  kardel  * Revision 4.2  1998/06/12 15:16:58  kardel
    598  1.1  kardel  * ansi2knr compatibility
    599  1.1  kardel  *
    600  1.1  kardel  * Revision 4.1  1998/05/24 07:59:56  kardel
    601  1.1  kardel  * conditional debug support
    602  1.1  kardel  *
    603  1.1  kardel  * Revision 4.0  1998/04/10 19:46:29  kardel
    604  1.1  kardel  * Start 4.0 release version numbering
    605  1.1  kardel  *
    606  1.1  kardel  * Revision 1.1  1998/04/10 19:27:46  kardel
    607  1.1  kardel  * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
    608  1.1  kardel  *
    609  1.1  kardel  * Revision 1.1  1997/10/06 21:05:45  kardel
    610  1.1  kardel  * new parse structure
    611  1.1  kardel  *
    612  1.1  kardel  */
    613