00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 # include "FP_bias.h"
00013 # include "FP_shift.h"
00014 # include "FP_trap.h"
00015 # include "FP_types.h"
00016 # include "get_put.h"
00017
00018 void
00019 compact(f,to,size)
00020 EXTEND *f;
00021 unsigned long *to;
00022 int size;
00023 {
00024 int error = 0;
00025
00026 if (size == sizeof(DOUBLE)) {
00027
00028
00029
00030 DOUBLE *DBL = (DOUBLE *) (void *) to;
00031
00032 if ((f->m1|(f->m2 & DBL_ZERO)) == 0L) {
00033 zrf8(DBL);
00034 return;
00035 }
00036 f->exp += DBL_BIAS;
00037 if (f->exp > DBL_MAX) {
00038 dbl_over: trap(EFOVFL);
00039 f->exp = DBL_MAX+1;
00040 f->m1 = 0;
00041 f->m2 = 0;
00042 if (error++)
00043 return;
00044 }
00045 else if (f->exp < DBL_MIN) {
00046 b64_rsft(&(f->mantissa));
00047 if (f->exp < 0) {
00048 b64_sft(&(f->mantissa), -f->exp);
00049 f->exp = 0;
00050 }
00051
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061 DBL->d[0] = f->m1 >> DBL_RUNPACK;
00062 DBL->d[1] = f->m2 >> DBL_RUNPACK;
00063 DBL->d[1] |= (f->m1 << DBL_LUNPACK);
00064
00065
00066
00067
00068 #ifdef EXCEPTION_INEXACT
00069 if ((f->m2 & DBL_EXACT) != 0) {
00070 INEXACT();
00071 #endif
00072 if (((f->m2 & DBL_EXACT) > DBL_ROUNDUP)
00073 || ((f->m2 & DBL_EXACT) == DBL_ROUNDUP
00074 && (f->m2 & (DBL_ROUNDUP << 1)))) {
00075 DBL->d[1]++;
00076 if (DBL->d[1] == 0L) {
00077 DBL->d[0]++;
00078
00079 if (f->exp == 0 && (DBL->d[0] & ~DBL_MASK)) {
00080 f->exp++;
00081 }
00082 if (DBL->d[0] & DBL_CARRYOUT) {
00083 if (DBL->d[0] & 01)
00084 DBL->d[1] = CARRYBIT;
00085 DBL->d[0] >>= 1;
00086 f->exp++;
00087 }
00088 }
00089
00090 if (f->exp > DBL_MAX)
00091 goto dbl_over;
00092 }
00093 #ifdef EXCEPTION_INEXACT
00094 }
00095 #endif
00096
00097
00098
00099
00100
00101
00102
00103
00104 DBL->d[0] &= DBL_MASK;
00105 DBL->d[0] |=
00106 ((long) (f->exp << DBL_EXPSHIFT) << EXP_STORE);
00107 if (f->sign)
00108 DBL->d[0] |= CARRYBIT;
00109
00110
00111
00112
00113
00114 #if FL_MSL_AT_LOW_ADDRESS
00115 put4(DBL->d[0], (char *) &DBL->d[0]);
00116 put4(DBL->d[1], (char *) &DBL->d[1]);
00117 #else
00118 { unsigned long l;
00119 put4(DBL->d[1], (char *) &l);
00120 put4(DBL->d[0], (char *) &DBL->d[1]);
00121 DBL->d[0] = l;
00122 }
00123 #endif
00124 }
00125 else {
00126
00127
00128
00129 SINGLE *SGL;
00130
00131
00132 SGL = (SINGLE *) (void *) to;
00133 if ((f->m1 & SGL_ZERO) == 0L) {
00134 *SGL = 0L;
00135 return;
00136 }
00137 f->exp += SGL_BIAS;
00138 if (f->exp > SGL_MAX) {
00139 sgl_over: trap(EFOVFL);
00140 f->exp = SGL_MAX+1;
00141 f->m1 = 0L;
00142 f->m2 = 0L;
00143 if (error++)
00144 return;
00145 }
00146 else if (f->exp < SGL_MIN) {
00147 b64_rsft(&(f->mantissa));
00148 if (f->exp < 0) {
00149 b64_sft(&(f->mantissa), -f->exp);
00150 f->exp = 0;
00151 }
00152
00153 }
00154
00155
00156 *SGL = (f->m1 >> SGL_RUNPACK);
00157
00158
00159
00160 #ifdef EXCEPTION_INEXACT
00161 if (f->m2 != 0 ||
00162 (f->m1 & SGL_EXACT) != 0L) {
00163 INEXACT();
00164 #endif
00165 if (((f->m1 & SGL_EXACT) > SGL_ROUNDUP)
00166 || ((f->m1 & SGL_EXACT) == SGL_ROUNDUP
00167 && (f->m1 & (SGL_ROUNDUP << 1)))) {
00168 (*SGL)++;
00169 if (f->exp == 0 && (*SGL & ~SGL_MASK)) {
00170 f->exp++;
00171 }
00172
00173 if (*SGL & SGL_CARRYOUT) {
00174 *SGL >>= 1;
00175 f->exp++;
00176 }
00177 if (f->exp > SGL_MAX)
00178 goto sgl_over;
00179 }
00180 #ifdef EXCEPTION_INEXACT
00181 }
00182 #endif
00183
00184
00185
00186
00187
00188
00189
00190
00191 *SGL &= SGL_MASK;
00192 *SGL |= ((long) (f->exp << SGL_EXPSHIFT) << EXP_STORE);
00193 if (f->sign)
00194 *SGL |= CARRYBIT;
00195
00196
00197
00198
00199
00200 put4(*SGL, (char *) &SGL);
00201 }
00202 }