Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "arith.internal.h"
00041
00042
00043
00044
00045
00046
00047 int
00048 ar_i32norm (signed int expo,
00049 unsigned long lbits,
00050 unsigned long rbits,
00051 AR_IEEE_32 *x,
00052 int roundmode) {
00053
00054 int res = AR_STAT_OK;
00055 unsigned long carry;
00056
00057 if (x->sign)
00058 res |= AR_STAT_NEGATIVE;
00059
00060
00061 if (!(lbits | x->coeff0 | x->coeff1 | rbits)) {
00062 x->expo = 0;
00063 return res | AR_STAT_ZERO;
00064 }
00065
00066
00067 while (expo > 1 && !lbits) {
00068 lbits = x->coeff0 >> (AR_IEEE32_C0_BITS - 1);
00069 SHLEFTIEEE32 (*x);
00070 x->coeff1 |= rbits >> (AR_IEEE32_ROUND_BITS - 1);
00071 rbits = (rbits << 1) & MASKR (AR_IEEE32_ROUND_BITS) | rbits & 1;
00072 expo--;
00073 }
00074 if (expo == 1 && !lbits)
00075 expo = 0;
00076 else if (!expo && lbits)
00077 expo = 1;
00078
00079
00080 while (lbits > 1 || expo < 0) {
00081 rbits = (rbits >> 1) |
00082 rbits & 1 |
00083 ((x->coeff1 & 1) << (AR_IEEE32_ROUND_BITS - 1));
00084 SHRIGHTIEEE32 (*x);
00085 x->coeff0 |= lbits << (AR_IEEE32_C0_BITS - 1);
00086 lbits >>= 1;
00087 expo++;
00088 }
00089
00090
00091 switch (roundmode) {
00092 case AR_ROUND_PLUS_INFINITY:
00093 if (!rbits == !x->sign)
00094 goto noround;
00095 break;
00096 case AR_ROUND_MINUS_INFINITY:
00097 if (!rbits != !x->sign)
00098 goto noround;
00099 break;
00100 case AR_ROUND_ZERO:
00101 goto noround;
00102 default:
00103 if (!(rbits >> (AR_IEEE32_ROUND_BITS - 1)))
00104 goto noround;
00105 if (!(rbits & MASKR (AR_IEEE32_ROUND_BITS - 1)) &&
00106 !(x->coeff1 & 1))
00107 goto noround;
00108 break;
00109 }
00110
00111
00112 carry = 1;
00113 INCIEEE32 (*x, carry);
00114 lbits += carry;
00115
00116 noround:
00117
00118
00119 if (lbits > 1) {
00120 rbits = (rbits >> 1) |
00121 ((x->coeff1 & 1) << (AR_IEEE32_ROUND_BITS - 1));
00122 SHRIGHTIEEE32 (*x);
00123 x->coeff0 |= lbits << (AR_IEEE32_C0_BITS - 1);
00124 lbits >>= 1;
00125 expo++;
00126 }
00127 else if (lbits) {
00128 if (!expo)
00129 expo = 1;
00130 }
00131 else
00132 expo = 0;
00133
00134 if (!(lbits | x->coeff0 | x->coeff1)) {
00135 expo = 0;
00136 res |= AR_STAT_ZERO | AR_STAT_UNDERFLOW;
00137 }
00138
00139
00140 if (expo > AR_IEEE32_MAX_EXPO) {
00141 x->expo = AR_IEEE32_MAX_EXPO + 1;
00142 x->coeff0 = x->coeff1 = 0;
00143 return res | AR_STAT_OVERFLOW;
00144 }
00145
00146
00147 if (rbits) {
00148 res |= AR_STAT_INEXACT;
00149 }
00150
00151 x->expo = expo;
00152
00153 if (!expo &&
00154 ar_state_register.ar_underflow_mode != AR_UNDERFLOW_TO_DENORM) {
00155
00156 if (x->coeff0 | x->coeff1) {
00157
00158 x->coeff0 = x->coeff1 = 0;
00159 if (ar_state_register.ar_underflow_mode ==
00160 AR_UNDERFLOW_TO_PLUS_ZERO)
00161 x->sign = 0;
00162 else if (ar_state_register.ar_underflow_mode ==
00163 AR_UNDERFLOW_TO_SIGNED_TINY)
00164 x->expo = AR_IEEE64_MIN_EXPO+1;
00165 return res | AR_STAT_ZERO | AR_STAT_UNDERFLOW;
00166 }
00167 }
00168
00169 return res;
00170 }
00171
00172
00173 int
00174 ar_i64norm (signed int expo,
00175 unsigned long lbits,
00176 unsigned long rbits,
00177 AR_IEEE_64 *x,
00178 int roundmode) {
00179
00180 int res = AR_STAT_OK;
00181 unsigned long carry;
00182
00183 if (x->sign)
00184 res |= AR_STAT_NEGATIVE;
00185
00186
00187 if (!(lbits | x->coeff0 | x->coeff1 | x->coeff2 | x->coeff3 | rbits)) {
00188 x->expo = 0;
00189 return res | AR_STAT_ZERO;
00190 }
00191
00192
00193 while (expo > 1 && !lbits) {
00194 lbits = x->coeff0 >> (AR_IEEE64_C0_BITS - 1);
00195 SHLEFTIEEE64 (*x);
00196 x->coeff3 |= rbits >> (AR_IEEE64_ROUND_BITS - 1);
00197 rbits = (rbits << 1) & MASKR (AR_IEEE64_ROUND_BITS) | rbits & 1;
00198 expo--;
00199 }
00200 if (expo == 1 && !lbits)
00201 expo = 0;
00202 else if (!expo && lbits)
00203 expo = 1;
00204
00205
00206 while (lbits > 1 || expo < 0) {
00207 rbits = (rbits >> 1) |
00208 rbits & 1 |
00209 ((x->coeff3 & 1) << (AR_IEEE64_ROUND_BITS - 1));
00210 SHRIGHTIEEE64 (*x);
00211 x->coeff0 |= lbits << (AR_IEEE64_C0_BITS - 1);
00212 lbits >>= 1;
00213 expo++;
00214 }
00215
00216
00217 switch (roundmode) {
00218 case AR_ROUND_PLUS_INFINITY:
00219 if (!rbits == !x->sign)
00220 goto noround;
00221 break;
00222 case AR_ROUND_MINUS_INFINITY:
00223 if (!rbits != !x->sign)
00224 goto noround;
00225 break;
00226 case AR_ROUND_ZERO:
00227 goto noround;
00228 default:
00229 if (!(rbits >> (AR_IEEE64_ROUND_BITS - 1)))
00230 goto noround;
00231 if (!(rbits & MASKR (AR_IEEE64_ROUND_BITS - 1)) &&
00232 !(x->coeff3 & 1))
00233 goto noround;
00234 break;
00235 }
00236
00237
00238 carry = 1;
00239 INCIEEE64 (*x, carry);
00240 lbits += carry;
00241
00242 noround:
00243
00244
00245 if (lbits > 1) {
00246 rbits = (rbits >> 1) |
00247 ((x->coeff3 & 1) << (AR_IEEE64_ROUND_BITS - 1));
00248 SHRIGHTIEEE64 (*x);
00249 x->coeff0 |= lbits << (AR_IEEE64_C0_BITS - 1);
00250 lbits >>= 1;
00251 expo++;
00252 }
00253 else if (lbits) {
00254 if (!expo)
00255 expo = 1;
00256 }
00257 else
00258 expo = 0;
00259
00260 if (!(lbits | x->coeff0 | x->coeff1 | x->coeff2 | x->coeff3)) {
00261 expo = 0;
00262 res |= AR_STAT_ZERO | AR_STAT_UNDERFLOW;
00263 }
00264
00265
00266 if (expo > AR_IEEE64_MAX_EXPO) {
00267 x->expo = AR_IEEE64_MAX_EXPO + 1;
00268 x->coeff0 = x->coeff1 = x->coeff2 = x->coeff3 = 0;
00269 return res | AR_STAT_OVERFLOW;
00270 }
00271
00272
00273 if (rbits) {
00274 res |= AR_STAT_INEXACT;
00275 }
00276
00277 x->expo = expo;
00278
00279 if (!expo &&
00280 ar_state_register.ar_underflow_mode != AR_UNDERFLOW_TO_DENORM) {
00281
00282 if (x->coeff0 | x->coeff1 | x->coeff2 | x->coeff3) {
00283
00284 x->coeff0 = x->coeff1 = x->coeff2 = x->coeff3 = 0;
00285 if (ar_state_register.ar_underflow_mode ==
00286 AR_UNDERFLOW_TO_PLUS_ZERO)
00287 x->sign = 0;
00288 else if (ar_state_register.ar_underflow_mode ==
00289 AR_UNDERFLOW_TO_SIGNED_TINY)
00290 x->expo = AR_IEEE64_MIN_EXPO+1;
00291 return res | AR_STAT_ZERO | AR_STAT_UNDERFLOW;
00292 }
00293 }
00294
00295 return res;
00296 }
00297
00298
00299 int
00300 ar_i128norm(signed int expo,
00301 unsigned long lbits,
00302 unsigned long rbits,
00303 AR_IEEE_128 *x,
00304 int roundmode) {
00305
00306 int res = AR_STAT_OK;
00307 unsigned long carry;
00308
00309 if (x->sign)
00310 res |= AR_STAT_NEGATIVE;
00311
00312
00313 if (!(lbits | x->coeff0 | x->coeff1 | x->coeff2 | x->coeff3 |
00314 x->coeff4 | x->coeff5 | x->coeff6 | rbits)) {
00315 x->expo = 0;
00316 return res | AR_STAT_ZERO;
00317 }
00318
00319
00320 while (expo > 1 && !lbits) {
00321 lbits = x->coeff0 >> (AR_IEEE128_C0_BITS - 1);
00322 SHLEFTIEEE128 (*x);
00323 x->coeff6 |= rbits >> (AR_IEEE128_ROUND_BITS - 1);
00324 rbits = (rbits << 1) & MASKR (AR_IEEE128_ROUND_BITS) | rbits & 1;
00325 expo--;
00326 }
00327 if (expo == 1 && !lbits)
00328 expo = 0;
00329 else if (!expo && lbits)
00330 expo = 1;
00331
00332
00333 while (lbits > 1 || expo < 0) {
00334 rbits = (rbits >> 1) |
00335 rbits & 1 |
00336 ((x->coeff6 & 1) << (AR_IEEE128_ROUND_BITS - 1));
00337 SHRIGHTIEEE128 (*x);
00338 x->coeff0 |= lbits << (AR_IEEE128_C0_BITS - 1);
00339 lbits >>= 1;
00340 expo++;
00341 }
00342
00343
00344 switch (roundmode) {
00345 case AR_ROUND_PLUS_INFINITY:
00346 if (!rbits == !x->sign)
00347 goto noround;
00348 break;
00349 case AR_ROUND_MINUS_INFINITY:
00350 if (!rbits != !x->sign)
00351 goto noround;
00352 break;
00353 case AR_ROUND_ZERO:
00354 goto noround;
00355 default:
00356 if (!(rbits >> (AR_IEEE128_ROUND_BITS - 1)))
00357 goto noround;
00358 if (!(rbits & MASKR (AR_IEEE128_ROUND_BITS - 1)) &&
00359 !(x->coeff6 & 1))
00360 goto noround;
00361 break;
00362 }
00363
00364
00365 carry = 1;
00366 INCIEEE128 (*x, carry);
00367 lbits += carry;
00368
00369 noround:
00370
00371
00372 if (lbits > 1) {
00373 rbits = (rbits >> 1) |
00374 ((x->coeff6 & 1) << (AR_IEEE128_ROUND_BITS - 1));
00375 SHRIGHTIEEE128 (*x);
00376 x->coeff0 |= lbits << (AR_IEEE128_C0_BITS - 1);
00377 lbits >>= 1;
00378 expo++;
00379 }
00380 else if (lbits) {
00381 if (!expo)
00382 expo = 1;
00383 }
00384 else
00385 expo = 0;
00386
00387 if (!(lbits | x->coeff0 | x->coeff1 | x->coeff2 | x->coeff3 |
00388 x->coeff4 | x->coeff5 | x->coeff6)) {
00389 expo = 0;
00390 res |= AR_STAT_ZERO | AR_STAT_UNDERFLOW;
00391 }
00392
00393
00394 if (expo > AR_IEEE128_MAX_EXPO) {
00395 x->expo = AR_IEEE128_MAX_EXPO + 1;
00396 x->coeff0 = x->coeff1 = x->coeff2 = x->coeff3 =
00397 x->coeff4 = x->coeff5 = x->coeff6 = 0;
00398 return res | AR_STAT_OVERFLOW;
00399 }
00400
00401
00402 if (rbits) {
00403 res |= AR_STAT_INEXACT;
00404 }
00405
00406 x->expo = expo;
00407
00408 if (!expo &&
00409 ar_state_register.ar_underflow_mode != AR_UNDERFLOW_TO_DENORM) {
00410
00411 if (x->coeff0 | x->coeff1 | x->coeff2 | x->coeff3 |
00412 x->coeff4 | x->coeff5 | x->coeff6) {
00413
00414 x->coeff0 = x->coeff1 = x->coeff2 = x->coeff3 =
00415 x->coeff4 = x->coeff5 = x->coeff6 = 0;
00416 if (ar_state_register.ar_underflow_mode ==
00417 AR_UNDERFLOW_TO_PLUS_ZERO)
00418 x->sign = 0;
00419 else if (ar_state_register.ar_underflow_mode ==
00420 AR_UNDERFLOW_TO_SIGNED_TINY)
00421 x->expo = AR_IEEE128_MIN_EXPO+1;
00422 return res | AR_STAT_ZERO | AR_STAT_UNDERFLOW;
00423 }
00424 }
00425
00426 return res;
00427 }
00428
00429
00430 static char USMID [] = "\n%Z%%M% %I% %G% %U%\n";
00431 static char rcsid [] = "$Id: ieee_norm.c,v 1.1.1.1 2002-05-22 20:06:19 dsystem Exp $";
00432