|
|
1.1 ! root 1: /* prim2real.c - presentation element to real */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/psap/RCS/prim2real.c,v 7.1 90/07/09 14:44:03 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/psap/RCS/prim2real.c,v 7.1 90/07/09 14:44:03 mrose Exp $ ! 9: * ! 10: * Contributed by Julian Onions, Nottingham University. ! 11: * July 1989 - this stuff is awful. If you're going to use it seriously then ! 12: * write a machine specific version rather than any attempt at portability. ! 13: * ! 14: * ! 15: * $Log: prim2real.c,v $ ! 16: * Revision 7.1 90/07/09 14:44:03 mrose ! 17: * sync ! 18: * ! 19: * Revision 7.0 89/11/23 22:13:14 mrose ! 20: * Release 6.0 ! 21: * ! 22: */ ! 23: ! 24: /* ! 25: * NOTICE ! 26: * ! 27: * Acquisition, use, and distribution of this module and related ! 28: * materials are subject to the restrictions of a license agreement. ! 29: * Consult the Preface in the User's Manual for the full terms of ! 30: * this agreement. ! 31: * ! 32: */ ! 33: ! 34: ! 35: /* LINTLIBRARY */ ! 36: ! 37: #include "psap.h" ! 38: ! 39: /* */ ! 40: ! 41: static double decode_binary (), decode_decimal (); ! 42: ! 43: double prim2real (pe) ! 44: register PE pe; ! 45: { ! 46: if (pe -> pe_form != PE_FORM_PRIM) ! 47: return pe_seterr (pe, PE_ERR_PRIM, NOTOK); ! 48: if (pe -> pe_len == 0) ! 49: return 0.0; ! 50: if (pe -> pe_prim == NULLPED) ! 51: return pe_seterr (pe, PE_ERR_PRIM, NOTOK); ! 52: ! 53: if (pe -> pe_len > sizeof (double) + 1) ! 54: return pe_seterr (pe, PE_ERR_OVER, NOTOK); ! 55: ! 56: pe -> pe_errno = PE_ERR_NONE; /* in case it's -1 */ ! 57: ! 58: if ((*(pe -> pe_prim) & 0x80) == 0x80) ! 59: return decode_binary (pe); ! 60: ! 61: switch (*(pe -> pe_prim) & PE_REAL_FLAGS) { ! 62: case PE_REAL_DECENC: ! 63: return decode_decimal (pe); ! 64: ! 65: case PE_REAL_SPECENC: ! 66: if (pe -> pe_len > 1) ! 67: return pe_seterr (pe, PE_ERR_OVER, NOTOK); ! 68: ! 69: switch (*(pe -> pe_prim)) { ! 70: case PE_REAL_MINUSINF: ! 71: return HUGE; ! 72: case PE_REAL_PLUSINF: ! 73: return -HUGE; ! 74: default: ! 75: return pe_seterr (pe, PE_ERR_NOSUPP, NOTOK); ! 76: } ! 77: } ! 78: /* NOTREACHED */ ! 79: } ! 80: ! 81: /* */ ! 82: ! 83: static double decode_binary (pe) ! 84: PE pe; ! 85: { ! 86: int sign, base, factor; ! 87: int exponent, i; ! 88: double mantissa, di; ! 89: PElementData dp, ep; ! 90: ! 91: dp = pe -> pe_prim; ! 92: sign = (*dp & PE_REAL_B_S) ? -1 : 1; ! 93: switch (*dp & PE_REAL_B_BASE) { ! 94: case PE_REAL_B_B2: ! 95: base = 2; ! 96: break; ! 97: ! 98: case PE_REAL_B_B8: ! 99: base = 8; ! 100: break; ! 101: ! 102: case PE_REAL_B_B16: ! 103: base = 16; ! 104: break; ! 105: default: ! 106: return pe_seterr(pe, PE_ERR_NOSUPP, NOTOK); ! 107: } ! 108: ! 109: factor = (*dp & PE_REAL_B_F) >> 2; ! 110: ! 111: exponent = (dp[1] & 0x80) ? (-1) : 0; ! 112: switch (*dp++ & PE_REAL_B_EXP) { ! 113: case PE_REAL_B_EF3: ! 114: exponent = (exponent << 8) | (*dp++ & 0xff); ! 115: /* fall */ ! 116: case PE_REAL_B_EF2: ! 117: exponent = (exponent << 8) | (*dp++ & 0xff); ! 118: /* fall */ ! 119: case PE_REAL_B_EF1: ! 120: exponent = (exponent << 8) | (*dp++ & 0xff); ! 121: break; ! 122: case PE_REAL_B_EF4: ! 123: i = *dp++ & 0xff; ! 124: if (i > sizeof(int)) ! 125: return pe_seterr (pe, PE_ERR_OVER, NOTOK); ! 126: for (; i > 0; i--) ! 127: exponent = (exponent << 8) | (*dp++ & 0xff); ! 128: break; ! 129: } ! 130: for (di = 0.0, ep = pe -> pe_prim + pe -> pe_len; dp < ep;) { ! 131: di *= 1 << 8; ; ! 132: di += (*dp++ & 0xff); ! 133: } ! 134: ! 135: mantissa = sign * di * (1 << factor); ! 136: return mantissa * pow ((double)base, (double)exponent); ! 137: } ! 138: ! 139: /* */ ! 140: ! 141: static double decode_decimal (pe) ! 142: PE pe; ! 143: { ! 144: /* sorry - don't have the standard ! */ ! 145: return pe_seterr (pe, PE_ERR_NOSUPP, NOTOK); ! 146: } ! 147:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.