|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 3128 (0xc38)
Types: TextFile
Names: »prim2real.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/psap/prim2real.c«
/* prim2real.c - presentation element to real */
#ifndef lint
static char *rcsid = "$Header: /f/osi/psap/RCS/prim2real.c,v 7.0 89/11/23 22:13:14 mrose Rel $";
#endif
/*
* $Header: /f/osi/psap/RCS/prim2real.c,v 7.0 89/11/23 22:13:14 mrose Rel $
*
* Contributed by Julian Onions, Nottingham University.
* July 1989 - this stuff is awful. If you're going to use it seriously then
* write a machine specific version rather than any attempt at portability.
*
*
* $Log: prim2real.c,v $
* Revision 7.0 89/11/23 22:13:14 mrose
* Release 6.0
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
/* LINTLIBRARY */
#include "psap.h"
/* \f
*/
static double decode_binary (), decode_decimal ();
double prim2real (pe)
register PE pe;
{
if (pe -> pe_form != PE_FORM_PRIM)
return pe_seterr (pe, PE_ERR_PRIM, NOTOK);
if (pe -> pe_len == 1)
return 0.0;
if (pe -> pe_prim == NULLPED)
return pe_seterr (pe, PE_ERR_PRIM, NOTOK);
if (pe -> pe_len > sizeof (double) + 1)
return pe_seterr (pe, PE_ERR_OVER, NOTOK);
pe -> pe_errno = PE_ERR_NONE; /* in case it's -1 */
if ((*(pe -> pe_prim) & 0x80) == 0x80)
return decode_binary (pe);
switch (*(pe -> pe_prim) & PE_REAL_FLAGS) {
case PE_REAL_DECENC:
return decode_decimal (pe);
case PE_REAL_SPECENC:
if (pe -> pe_len > 1)
return pe_seterr (pe, PE_ERR_OVER, NOTOK);
switch (*(pe -> pe_prim)) {
case PE_REAL_MINUSINF:
return HUGE;
case PE_REAL_PLUSINF:
return -HUGE;
default:
return pe_seterr (pe, PE_ERR_NOSUPP, NOTOK);
}
}
/* NOTREACHED */
}
/* \f
*/
static double decode_binary (pe)
PE pe;
{
int sign, base, factor;
int exponent, i;
double mantissa, di;
PElementData dp, ep;
dp = pe -> pe_prim;
sign = (*dp & PE_REAL_B_S) ? -1 : 1;
switch (*dp & PE_REAL_B_BASE) {
case PE_REAL_B_B2:
base = 2;
break;
case PE_REAL_B_B8:
base = 8;
break;
case PE_REAL_B_B16:
base = 16;
break;
default:
return pe_seterr(pe, PE_ERR_NOSUPP, NOTOK);
}
factor = (*dp & PE_REAL_B_F) >> 2;
exponent = (dp[1] & 0x80) ? (-1) : 0;
switch (*dp++ & PE_REAL_B_EXP) {
case PE_REAL_B_EF3:
exponent = (exponent << 8) | (*dp++ & 0xff);
/* fall */
case PE_REAL_B_EF2:
exponent = (exponent << 8) | (*dp++ & 0xff);
/* fall */
case PE_REAL_B_EF1:
exponent = (exponent << 8) | (*dp++ & 0xff);
break;
case PE_REAL_B_EF4:
i = *dp++ & 0xff;
if (i > sizeof(int))
return pe_seterr (pe, PE_ERR_OVER, NOTOK);
for (; i > 0; i--)
exponent = (exponent << 8) | (*dp++ & 0xff);
break;
}
for (di = 0.0, ep = pe -> pe_prim + pe -> pe_len; dp < ep;) {
di *= 1 << 8; ;
di += (*dp++ & 0xff);
}
mantissa = sign * di * (1 << factor);
return mantissa * pow ((double)base, (double)exponent);
}
/* \f
*/
static double decode_decimal (pe)
PE pe;
{
/* sorry - don't have the standard ! */
return pe_seterr (pe, PE_ERR_NOSUPP, NOTOK);
}