386BSD 0.1 development
[unix-history] / usr / othersrc / contrib / isode / psap / real2prim.c
CommitLineData
cf908fd1
WJ
1/* real2prim.c - real to presentation element */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/psap/RCS/real2prim.c,v 7.1 91/02/22 09:36:50 mrose Interim $";
5#endif
6
7/*
8 * $Header: /f/osi/psap/RCS/real2prim.c,v 7.1 91/02/22 09:36:50 mrose Interim $
9 *
10 * Contributed by Julian Onions, Nottingham University.
11 * July 1989 - this is awful stuff!
12 *
13 8
14 * $Log: real2prim.c,v $
15 * Revision 7.1 91/02/22 09:36:50 mrose
16 * Interim 6.8
17 *
18 * Revision 7.0 89/11/23 22:13:34 mrose
19 * Release 6.0
20 *
21 */
22
23/*
24 * NOTICE
25 *
26 * Acquisition, use, and distribution of this module and related
27 * materials are subject to the restrictions of a license agreement.
28 * Consult the Preface in the User's Manual for the full terms of
29 * this agreement.
30 *
31 */
32
33
34/* LINTLIBRARY */
35
36#include "psap.h"
37
38/* \f */
39
40PE real2prim (d, class, id)
41register double d;
42PElementClass class;
43PElementID id;
44{
45 register PE pe;
46 double mant, nm;
47 int exponent;
48 int expsign;
49 int parts[sizeof (double)];
50 int sign, i, maxi, mask;
51 int n, explen;
52 PElementData dp;
53
54 if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
55 return NULLPE;
56
57 if (d == 0.0)
58 return pe;
59
60 mant = frexp (d, &exponent);
61
62 if (mant < 0.0) {
63 sign = -1;
64 mant = -mant;
65 }
66 else sign = 1;
67
68 nm = mant;
69 for (i = 0; i < sizeof (double) ; i++) {
70 int intnm;
71 nm *= (1<<8);
72 intnm = ((int)nm) & 0xff;
73 nm -= intnm;
74 if (intnm)
75 maxi = i + 1;
76 parts[i] = intnm;
77 }
78
79 exponent -= 8 * maxi;
80
81 expsign = exponent >= 0 ? exponent : exponent ^ (-1);
82 mask = 0x1ff << (((n = sizeof exponent) - 1) * 8 - 1);
83 while (n > 1 && (expsign & mask) == 0)
84 mask >>= 8, n--;
85
86 explen = n;
87 if (n > 3)
88 n ++;
89
90 if ((pe -> pe_prim = PEDalloc (n + maxi + 1)) == NULLPED) {
91 pe_free (pe);
92 return NULLPE;
93 }
94
95 dp = pe -> pe_prim + (pe -> pe_len = n + maxi + 1);
96
97 for (; maxi > 0; maxi --)
98 *--dp = parts[maxi - 1];
99 for (n = explen; n-- > 0; exponent >>= 8)
100 *--dp = exponent & 0xff;
101 if (explen > 3)
102 *--dp = explen & 0xff;
103
104 switch (explen) {
105 case 1:
106 explen = PE_REAL_B_EF1;
107 break;
108 case 2:
109 explen = PE_REAL_B_EF2;
110 break;
111 case 3:
112 explen = PE_REAL_B_EF3;
113 break;
114 default:
115 explen = PE_REAL_B_EF3;
116 break;
117 }
118 *--dp = PE_REAL_BINENC
119 | PE_REAL_B_B2
120 | (sign == -1 ? PE_REAL_B_S : 0)
121 | explen;
122 return pe;
123}
124
125
126
127