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
00035 #include <sftypes.h>
00036 #include <common.h>
00037
00038
00039 char zeroTable[256] = {
00040 8, 7, 7, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, \
00041 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
00042 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
00043 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
00044 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
00045 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
00046 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
00047 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
00048 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
00049 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
00050 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
00051 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
00052 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
00053 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
00054 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
00055 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00056 };
00057
00058
00059
00066 float64 finishFloat64(int32_t cexp, uint64_t cfrac, char sign)
00067 {
00068 float64 result;
00069
00070 result.parts.sign = sign;
00071
00072
00073 while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1 ) )))) {
00074 cexp--;
00075 cfrac <<= 1;
00076
00077 };
00078
00079 if ((cexp < 0) || ( cexp == 0 && (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))))) {
00080
00081 result.parts.exp = 0;
00082 if ((cexp + FLOAT64_FRACTION_SIZE + 1) < 0) {
00083 result.parts.fraction = 0;
00084 return result;
00085 }
00086
00087 while (cexp < 0) {
00088 cexp++;
00089 cfrac >>= 1;
00090 }
00091
00092 cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
00093
00094 if (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))) {
00095
00096 result.parts.fraction = ((cfrac >>(64 - FLOAT64_FRACTION_SIZE - 2) ) & (~FLOAT64_HIDDEN_BIT_MASK));
00097 return result;
00098 }
00099 } else {
00100 cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
00101 }
00102
00103 ++cexp;
00104
00105 if (cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1 ))) {
00106 ++cexp;
00107 cfrac >>= 1;
00108 }
00109
00110
00111 if (cexp >= FLOAT64_MAX_EXPONENT ) {
00112
00113 result.parts.exp = FLOAT64_MAX_EXPONENT;
00114 result.parts.fraction = 0;
00115 return result;
00116 }
00117
00118 result.parts.exp = (uint32_t)cexp;
00119
00120 result.parts.fraction = ((cfrac >>(64 - FLOAT64_FRACTION_SIZE - 2 ) ) & (~FLOAT64_HIDDEN_BIT_MASK));
00121
00122 return result;
00123 }
00124
00128 int countZeroes64(uint64_t i)
00129 {
00130 int j;
00131 for (j =0; j < 64; j += 8) {
00132 if ( i & (0xFFll << (56 - j))) {
00133 return (j + countZeroes8(i >> (56 - j)));
00134 }
00135 }
00136
00137 return 64;
00138 }
00139
00143 int countZeroes32(uint32_t i)
00144 {
00145 int j;
00146 for (j =0; j < 32; j += 8) {
00147 if ( i & (0xFF << (24 - j))) {
00148 return (j + countZeroes8(i >> (24 - j)));
00149 }
00150 }
00151
00152 return 32;
00153 }
00154
00158 int countZeroes8(uint8_t i)
00159 {
00160 return zeroTable[i];
00161 }
00162
00167 void roundFloat32(int32_t *exp, uint32_t *fraction)
00168 {
00169
00170 (*fraction) += (0x1 << 6);
00171
00172 if ((*fraction) & (FLOAT32_HIDDEN_BIT_MASK << 8)) {
00173
00174 ++(*exp);
00175 (*fraction) >>= 1;
00176 };
00177
00178 if (((*exp) >= FLOAT32_MAX_EXPONENT ) || ((*exp) < 0)) {
00179
00180 (*exp) = FLOAT32_MAX_EXPONENT;
00181 (*fraction) = 0;
00182 return;
00183 }
00184
00185 return;
00186 }
00187
00192 void roundFloat64(int32_t *exp, uint64_t *fraction)
00193 {
00194
00195 (*fraction) += (0x1 << 9);
00196
00197 if ((*fraction) & (FLOAT64_HIDDEN_BIT_MASK << 11)) {
00198
00199 ++(*exp);
00200 (*fraction) >>= 1;
00201 };
00202
00203 if (((*exp) >= FLOAT64_MAX_EXPONENT ) || ((*exp) < 0)) {
00204
00205 (*exp) = FLOAT64_MAX_EXPONENT;
00206 (*fraction) = 0;
00207 return;
00208 }
00209
00210 return;
00211 }
00212