|
|
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.