159 lines
5.4 KiB
C
159 lines
5.4 KiB
C
/***************************************************************************/
|
|
/* */
|
|
/* Project : Mil-Std-1750 Host Development Support Library */
|
|
/* */
|
|
/* Component : flt1750.c -- host independent float conversion routines */
|
|
/* */
|
|
/* Copyright : (C) Daimler-Benz Aerospace AG, 1994-97 */
|
|
/* */
|
|
/* Author : Oliver M. Kellogg, Dornier Satellite Systems, */
|
|
/* Dept. RST13, D-81663 Munich, Germany. */
|
|
/* Contact : oliver.kellogg@space.otn.dasa.de */
|
|
/* */
|
|
/* Disclaimer: */
|
|
/* */
|
|
/* This program is free software; you can redistribute it and/or modify */
|
|
/* it under the terms of the GNU General Public License as published by */
|
|
/* the Free Software Foundation; either version 2 of the License, or */
|
|
/* (at your option) any later version. */
|
|
/* */
|
|
/* This program is distributed in the hope that it will be useful, */
|
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
|
/* GNU General Public License for more details. */
|
|
/* */
|
|
/* You should have received a copy of the GNU General Public License */
|
|
/* along with this program; if not, write to the Free Software */
|
|
/* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
/* */
|
|
/***************************************************************************/
|
|
|
|
/* These conversion functions have been tested on MIPS(ULTRIX), SPARC(Solaris),
|
|
i386(Linux/DOS), and VAX(VMS) machines. Should you encounter any problems
|
|
on other machines, please write to the e-mail contact address given above.
|
|
*/
|
|
|
|
|
|
#include "codeflt1750.h"
|
|
#include <math.h>
|
|
#define dfrexp frexp
|
|
#define pow2(exp) pow(2.0,(double)exp)
|
|
|
|
#define ushort unsigned short
|
|
#define ulong unsigned long
|
|
|
|
#define FLOATING_TWO_TO_THE_FIFTEEN 32768.0
|
|
#define FLOATING_TWO_TO_THE_TWENTYTHREE 8388608.0
|
|
#define FLOATING_TWO_TO_THE_THIRTYONE 2147483648.0
|
|
#define FLOATING_TWO_TO_THE_THIRTYNINE 549755813888.0
|
|
|
|
|
|
|
|
double
|
|
from_1750flt (short *input) /* input : array of 2 shorts */
|
|
{
|
|
long int_mant;
|
|
double flt_mant, flt_exp;
|
|
signed char int_exp;
|
|
|
|
int_exp = (signed char) (input[1] & 0xFF);
|
|
int_mant = ((long) input[0] << 8) | (((long) input[1] & 0xFF00L) >> 8);
|
|
/* printf("int_mant = 0x%08lx\n",int_mant); */
|
|
flt_mant = (double) int_mant / FLOATING_TWO_TO_THE_TWENTYTHREE;
|
|
flt_exp = pow2 (int_exp);
|
|
return flt_mant * flt_exp;
|
|
}
|
|
|
|
int
|
|
to_1750flt (double input, short output[2])
|
|
{
|
|
int exp;
|
|
long mant;
|
|
|
|
input = dfrexp (input, &exp);
|
|
|
|
if (exp < -128)
|
|
return -1; /* signalize underflow */
|
|
else if (exp > 127)
|
|
return 1; /* signalize overflow */
|
|
|
|
if (input < 0.0 && input >= -0.5) /* prompted by UNIX frexp */
|
|
{
|
|
input *= 2.0;
|
|
exp--;
|
|
}
|
|
|
|
mant = (long) (input * FLOATING_TWO_TO_THE_THIRTYONE);
|
|
|
|
/* printf("\n\tmant=%08lx\n",mant); */
|
|
output[0] = (short) (mant >> 16);
|
|
output[1] = (short) (mant & 0xFF00) | (exp & 0xFF);
|
|
|
|
return 0; /* success status */
|
|
}
|
|
|
|
double
|
|
from_1750eflt (short *input) /* input : array of 3 shorts */
|
|
{
|
|
long int_mant_hi, int_mant_lo;
|
|
double flt_mant, flt_exp;
|
|
signed char int_exp;
|
|
|
|
int_exp = (signed char) (input[1] & 0xFF);
|
|
|
|
int_mant_hi = (((long) input[0] << 16) | ((long) input[1] & 0xFF00L)) >> 8;
|
|
int_mant_lo = ((long) input[2] & 0xFFFFL);
|
|
|
|
flt_mant = (double) int_mant_hi / FLOATING_TWO_TO_THE_TWENTYTHREE
|
|
+ (double) int_mant_lo / FLOATING_TWO_TO_THE_THIRTYNINE;
|
|
flt_exp = pow2 (int_exp);
|
|
/* printf ("\tfrom: mant=%.12g, exp=%g\n", flt_mant, flt_exp); */
|
|
|
|
return flt_mant * flt_exp;
|
|
}
|
|
|
|
int
|
|
to_1750eflt (double input, short output[3])
|
|
{
|
|
int exp;
|
|
int is_neg = 0;
|
|
ushort hlp;
|
|
|
|
if (input < 0.0)
|
|
{
|
|
is_neg = 1;
|
|
input = -input - .03125 / FLOATING_TWO_TO_THE_THIRTYNINE;
|
|
}
|
|
|
|
input = dfrexp (input, &exp); /* input is now normalized mantissa */
|
|
|
|
if (input == 1.0) /* prompted by VAX frexp */
|
|
{
|
|
input = 0.5;
|
|
exp++;
|
|
}
|
|
|
|
if (exp < -128)
|
|
return -1; /* signalize underflow */
|
|
else if (exp > 127)
|
|
return 1; /* signalize overflow */
|
|
|
|
output[0] = (short) (input * FLOATING_TWO_TO_THE_FIFTEEN);
|
|
input -= (double) output[0] / FLOATING_TWO_TO_THE_FIFTEEN;
|
|
hlp = (ushort) (input * FLOATING_TWO_TO_THE_TWENTYTHREE);
|
|
output[1] = (short) ((hlp << 8) | (exp & 0xFF));
|
|
input -= (double) hlp / FLOATING_TWO_TO_THE_TWENTYTHREE;
|
|
hlp = (ushort) (input * FLOATING_TWO_TO_THE_THIRTYNINE);
|
|
output[2] = (short) hlp;
|
|
|
|
if (is_neg)
|
|
{
|
|
output[0] = ~output[0];
|
|
output[1] = (~output[1] & 0xFF00) | (output[1] & 0x00FF);
|
|
output[2] = ~output[2];
|
|
}
|
|
|
|
return 0; /* success status */
|
|
}
|
|
|