/*
* /src/NTP/ntp4-dev/libntp/ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
*
* ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
*
* $Created: Sun Jul 13 09:12:02 1997 $
*
* Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/*
* make conversions to and from external IEEE754 formats and internal
* NTP FP format.
*/
int
fetch_ieee754(
unsigned char **buffpp,
int size,
l_fp *lfpp,
offsets_t offsets
)
{
unsigned char *bufp = *buffpp;
unsigned int sign;
unsigned int bias;
unsigned int maxexp;
int mbits;
u_long mantissa_low;
u_long mantissa_high;
u_long characteristic;
long exponent;
#ifdef LIBDEBUG
int length;
#endif
unsigned char val;
int fieldindex = 0;
if (exponent > 31) /* sorry - hardcoded */
{
/*
* overflow only in respect to NTP-FP representation
*/
return sign ? IEEE_NEGOVERFLOW : IEEE_POSOVERFLOW;
}
else
{
int frac_offset; /* where the fraction starts */
frac_offset = mbits - exponent;
if (characteristic == 0)
{
/*
* de-normalized or tiny number - fits only as 0
*/
return IEEE_OK;
}
else
{
/*
* adjust for implied 1
*/
if (mbits > 31)
mantissa_high |= 1 << (mbits - 32);
else
mantissa_low |= 1 << mbits;
/*
* take mantissa apart - if only all machine would support
* 64 bit operations 8-(
*/
if (frac_offset > mbits)
{
lfpp->l_ui = 0; /* only fractional number */
frac_offset -= mbits + 1; /* will now contain right shift count - 1*/
if (mbits > 31)
{
lfpp->l_uf = mantissa_high << (63 - mbits);
lfpp->l_uf |= mantissa_low >> (mbits - 33);
lfpp->l_uf >>= frac_offset;
}
else
{
lfpp->l_uf = mantissa_low >> frac_offset;
}
}
else
{
if (frac_offset > 32)
{
/*
* must split in high word
*/
lfpp->l_ui = mantissa_high >> (frac_offset - 32);
lfpp->l_uf = (mantissa_high & ((1 << (frac_offset - 32)) - 1)) << (64 - frac_offset);
lfpp->l_uf |= mantissa_low >> (frac_offset - 32);
}
else
{
/*
* must split in low word
*/
lfpp->l_ui = mantissa_high << (32 - frac_offset);
lfpp->l_ui |= (mantissa_low >> frac_offset) & ((1 << (32 - frac_offset)) - 1);
lfpp->l_uf = (mantissa_low & ((1 << frac_offset) - 1)) << (32 - frac_offset);
}
}
/*
* adjust for sign
*/
if (sign)
{
L_NEG(lfpp);
}
return IEEE_OK;
}
}
}
}
/*
* DLH: This function is currently unused in ntpd. If you think about
* using it, be sure it does what you intend. I notice the bufpp arg
* is never referenced, and the calculated mantissa_high & mantissa_low
* are only referenced in debug output. It seems they're supposed to
* be composed into an ieee754-format float and stored at *bufpp or
* possibly **bufpp. Brought to my attention by this:
*
* ieee754io.c:414:10: warning: variable 'mantissa_low' set but not used
* [-Wunused-but-set-variable]
*
* To quiet it I'm #ifdef'ing the function away for now, here and below
* the call to it in main().
*/
#ifdef PUT_IEEE754_UNUSED_FUNC
int
put_ieee754(
unsigned char **bufpp,
int size,
l_fp *lfpp,
offsets_t offsets
)
{
l_fp outlfp;
#ifdef LIBDEBUG
unsigned int sign;
unsigned int bias;
#endif
/*unsigned int maxexp;*/
int mbits;
int msb;
u_long mantissa_low = 0;
u_long mantissa_high = 0;
#ifdef LIBDEBUG
u_long characteristic = 0;
long exponent;
#endif
/*int length;*/
unsigned long mask;