Rev 731 | Rev 1031 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 731 | Rev 734 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
27 | */ |
28 | 28 | ||
29 | #include "sftypes.h" |
29 | #include<sftypes.h> |
30 | #include "sub.h" |
30 | #include<sub.h> |
- | 31 | #include<comparison.h> |
|
31 | 32 | ||
32 | /** Subtract two float32 numbers with same signs |
33 | /** Subtract two float32 numbers with same signs |
33 | */ |
34 | */ |
34 | float32 subFloat32(float32 a, float32 b) |
35 | float32 subFloat32(float32 a, float32 b) |
35 | { |
36 | { |
36 | int expdiff; |
37 | int expdiff; |
37 | __u32 exp1,exp2,mant1,mant2; |
38 | __u32 exp1, exp2, mant1, mant2; |
38 | float32 result; |
39 | float32 result; |
39 | 40 | ||
40 | result.f = 0; |
41 | result.f = 0; |
41 | 42 | ||
42 | expdiff=a.parts.exp - b.parts.exp; |
43 | expdiff = a.parts.exp - b.parts.exp; |
43 | if ((expdiff<0)||((expdiff==0)&&(a.parts.mantisa<b.parts.mantisa))) { |
44 | if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.mantisa < b.parts.mantisa))) { |
44 | if (isFloat32NaN(b)) { |
45 | if (isFloat32NaN(b)) { |
45 | //TODO: fix SigNaN |
46 | //TODO: fix SigNaN |
46 | if (isFloat32SigNaN(b)) { |
47 | if (isFloat32SigNaN(b)) { |
47 | }; |
48 | }; |
48 | return b; |
49 | return b; |
49 | }; |
50 | }; |
50 | 51 | ||
51 | if (b.parts.exp==0xFF) { |
52 | if (b.parts.exp == FLOAT32_MAX_EXPONENT) { |
52 | b.parts.sign=!b.parts.sign; /* num -(+-inf) = -+inf */ |
53 | b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */ |
53 | return b; |
54 | return b; |
54 | } |
55 | } |
55 | 56 | ||
56 | result.parts.sign = !a.parts.sign; |
57 | result.parts.sign = !a.parts.sign; |
57 | 58 | ||
58 | mant1=b.parts.mantisa; |
59 | mant1 = b.parts.mantisa; |
59 | exp1=b.parts.exp; |
60 | exp1 = b.parts.exp; |
60 | mant2=a.parts.mantisa; |
61 | mant2 = a.parts.mantisa; |
61 | exp2=a.parts.exp; |
62 | exp2 = a.parts.exp; |
62 | expdiff*=-1; |
63 | expdiff *= -1; |
63 | } else { |
64 | } else { |
64 | if (isFloat32NaN(a)) { |
65 | if (isFloat32NaN(a)) { |
65 | //TODO: fix SigNaN |
66 | //TODO: fix SigNaN |
66 | if ((isFloat32SigNaN(a))||(isFloat32SigNaN(b))) { |
67 | if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) { |
67 | }; |
68 | }; |
68 | return a; |
69 | return a; |
69 | }; |
70 | }; |
70 | 71 | ||
71 | if (a.parts.exp==0xFF) { |
72 | if (a.parts.exp == FLOAT32_MAX_EXPONENT) { |
72 | if (b.parts.exp==0xFF) { |
73 | if (b.parts.exp == FLOAT32_MAX_EXPONENT) { |
73 | /* inf - inf => nan */ |
74 | /* inf - inf => nan */ |
74 | //TODO: fix exception |
75 | //TODO: fix exception |
75 | result.binary = FLOAT32_NAN; |
76 | result.binary = FLOAT32_NAN; |
76 | return result; |
77 | return result; |
77 | }; |
78 | }; |
78 | return a; |
79 | return a; |
79 | } |
80 | } |
80 | 81 | ||
81 | result.parts.sign = a.parts.sign; |
82 | result.parts.sign = a.parts.sign; |
82 | 83 | ||
83 | mant1=a.parts.mantisa; |
84 | mant1 = a.parts.mantisa; |
84 | exp1=a.parts.exp; |
85 | exp1 = a.parts.exp; |
85 | mant2=b.parts.mantisa; |
86 | mant2 = b.parts.mantisa; |
86 | exp2=b.parts.exp; |
87 | exp2 = b.parts.exp; |
87 | }; |
88 | }; |
88 | 89 | ||
89 | if (exp1==0) { |
90 | if (exp1 == 0) { |
90 | //both are denormalized |
91 | //both are denormalized |
91 | result.parts.mantisa=mant1-mant2; |
92 | result.parts.mantisa = mant1-mant2; |
92 | if (result.parts.mantisa>mant1) { |
93 | if (result.parts.mantisa > mant1) { |
93 | //TODO: underflow exception |
94 | //TODO: underflow exception |
94 | return result; |
95 | return result; |
95 | }; |
96 | }; |
96 | result.parts.exp=0; |
97 | result.parts.exp = 0; |
97 | return result; |
98 | return result; |
98 | }; |
99 | }; |
- | 100 | ||
- | 101 | /* add hidden bit */ |
|
- | 102 | mant1 |= FLOAT32_HIDDEN_BIT_MASK; |
|
- | 103 | ||
- | 104 | if (exp2 == 0) { |
|
- | 105 | /* denormalized */ |
|
- | 106 | --expdiff; |
|
- | 107 | } else { |
|
- | 108 | /* normalized */ |
|
- | 109 | mant2 |= FLOAT32_HIDDEN_BIT_MASK; |
|
- | 110 | }; |
|
- | 111 | ||
- | 112 | /* create some space for rounding */ |
|
- | 113 | mant1 <<= 6; |
|
- | 114 | mant2 <<= 6; |
|
- | 115 | ||
- | 116 | if (expdiff > FLOAT32_MANTISA_SIZE + 1) { |
|
- | 117 | goto done; |
|
- | 118 | }; |
|
99 | 119 | ||
100 | // create some space for rounding |
120 | mant1 = mant1 - (mant2 >> expdiff); |
- | 121 | done: |
|
- | 122 | //TODO: find first nonzero digit and shift result and detect possibly underflow |
|
- | 123 | while ((exp1 > 0) && (!(mant1 & (FLOAT32_HIDDEN_BIT_MASK << 6 )))) { |
|
101 | mant1<<=6; |
124 | --exp1; |
102 | mant2<<=6; |
125 | mant1 <<= 1; |
- | 126 | /* TODO: fix underflow - mant1 == 0 does not necessary means underflow... */ |
|
- | 127 | }; |
|
103 | 128 | ||
- | 129 | /* rounding - if first bit after mantisa is set then round up */ |
|
- | 130 | mant1 += 0x20; |
|
- | 131 | ||
- | 132 | if (mant1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) { |
|
- | 133 | ++exp1; |
|
- | 134 | mant1 >>= 1; |
|
- | 135 | }; |
|
- | 136 | ||
104 | mant1|=0x20000000; //add hidden bit |
137 | /*Clear hidden bit and shift */ |
- | 138 | result.parts.mantisa = ((mant1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); |
|
- | 139 | result.parts.exp = exp1; |
|
- | 140 | ||
- | 141 | return result; |
|
- | 142 | } |
|
- | 143 | ||
- | 144 | /** Subtract two float64 numbers with same signs |
|
- | 145 | */ |
|
- | 146 | float64 subFloat64(float64 a, float64 b) |
|
- | 147 | { |
|
- | 148 | int expdiff; |
|
- | 149 | __u32 exp1, exp2; |
|
- | 150 | __u64 mant1, mant2; |
|
- | 151 | float64 result; |
|
- | 152 | ||
- | 153 | result.d = 0; |
|
- | 154 | ||
- | 155 | expdiff = a.parts.exp - b.parts.exp; |
|
- | 156 | if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.mantisa < b.parts.mantisa))) { |
|
- | 157 | if (isFloat64NaN(b)) { |
|
- | 158 | //TODO: fix SigNaN |
|
- | 159 | if (isFloat64SigNaN(b)) { |
|
- | 160 | }; |
|
- | 161 | return b; |
|
- | 162 | }; |
|
- | 163 | ||
- | 164 | if (b.parts.exp == FLOAT64_MAX_EXPONENT) { |
|
- | 165 | b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */ |
|
- | 166 | return b; |
|
- | 167 | } |
|
- | 168 | ||
- | 169 | result.parts.sign = !a.parts.sign; |
|
- | 170 | ||
- | 171 | mant1 = b.parts.mantisa; |
|
- | 172 | exp1 = b.parts.exp; |
|
- | 173 | mant2 = a.parts.mantisa; |
|
- | 174 | exp2 = a.parts.exp; |
|
- | 175 | expdiff *= -1; |
|
- | 176 | } else { |
|
- | 177 | if (isFloat64NaN(a)) { |
|
- | 178 | //TODO: fix SigNaN |
|
- | 179 | if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) { |
|
- | 180 | }; |
|
- | 181 | return a; |
|
- | 182 | }; |
|
- | 183 | ||
- | 184 | if (a.parts.exp == FLOAT64_MAX_EXPONENT) { |
|
- | 185 | if (b.parts.exp == FLOAT64_MAX_EXPONENT) { |
|
- | 186 | /* inf - inf => nan */ |
|
- | 187 | //TODO: fix exception |
|
- | 188 | result.binary = FLOAT64_NAN; |
|
- | 189 | return result; |
|
- | 190 | }; |
|
- | 191 | return a; |
|
- | 192 | } |
|
- | 193 | ||
- | 194 | result.parts.sign = a.parts.sign; |
|
- | 195 | ||
- | 196 | mant1 = a.parts.mantisa; |
|
- | 197 | exp1 = a.parts.exp; |
|
- | 198 | mant2 = b.parts.mantisa; |
|
- | 199 | exp2 = b.parts.exp; |
|
- | 200 | }; |
|
105 | 201 | ||
- | 202 | if (exp1 == 0) { |
|
- | 203 | //both are denormalized |
|
- | 204 | result.parts.mantisa = mant1 - mant2; |
|
- | 205 | if (result.parts.mantisa > mant1) { |
|
- | 206 | //TODO: underflow exception |
|
- | 207 | return result; |
|
- | 208 | }; |
|
- | 209 | result.parts.exp = 0; |
|
- | 210 | return result; |
|
- | 211 | }; |
|
- | 212 | ||
- | 213 | /* add hidden bit */ |
|
- | 214 | mant1 |= FLOAT64_HIDDEN_BIT_MASK; |
|
106 | 215 | ||
107 | if (exp2==0) { |
216 | if (exp2 == 0) { |
- | 217 | /* denormalized */ |
|
108 | --expdiff; |
218 | --expdiff; |
109 | } else { |
219 | } else { |
- | 220 | /* normalized */ |
|
110 | mant2|=0x20000000; //hidden bit |
221 | mant2 |= FLOAT64_HIDDEN_BIT_MASK; |
111 | }; |
222 | }; |
112 | 223 | ||
- | 224 | /* create some space for rounding */ |
|
- | 225 | mant1 <<= 6; |
|
- | 226 | mant2 <<= 6; |
|
- | 227 | ||
113 | if (expdiff>24) { |
228 | if (expdiff > FLOAT64_MANTISA_SIZE + 1) { |
114 | goto done; |
229 | goto done; |
115 | }; |
230 | }; |
116 | 231 | ||
117 | mant1 = mant1-(mant2>>expdiff); |
232 | mant1 = mant1 - (mant2 >> expdiff); |
118 | done: |
233 | done: |
119 | //TODO: find first nonzero digit and shift result and detect possibly underflow |
234 | //TODO: find first nonzero digit and shift result and detect possibly underflow |
120 | while ((exp1>0)&&(!(mant1&0x20000000))) { |
235 | while ((exp1 > 0) && (!(mant1 & (FLOAT64_HIDDEN_BIT_MASK << 6 )))) { |
121 | exp1--; |
236 | --exp1; |
122 | mant1 <<= 1; |
237 | mant1 <<= 1; |
123 | /* TODO: fix underflow - mant1 == 0 does not necessary means underflow... */ |
238 | /* TODO: fix underflow - mant1 == 0 does not necessary means underflow... */ |
124 | }; |
239 | }; |
125 | 240 | ||
126 | //rounding - if first bit after mantisa is set then round up |
241 | /* rounding - if first bit after mantisa is set then round up */ |
127 | mant1 += 0x20; |
242 | mant1 += 0x20; |
128 | 243 | ||
129 | if (mant1&0x40000000) { |
244 | if (mant1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) { |
130 | ++exp1; |
245 | ++exp1; |
131 | mant1>>=1; |
246 | mant1 >>= 1; |
132 | }; |
247 | }; |
133 | 248 | ||
- | 249 | /*Clear hidden bit and shift */ |
|
134 | result.parts.mantisa = ((mant1&(~0x20000000))>>6); /*Clear hidden bit and shift */ |
250 | result.parts.mantisa = ((mant1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK)); |
135 | result.parts.exp = exp1; |
251 | result.parts.exp = exp1; |
136 | 252 | ||
137 | return result; |
253 | return result; |
138 | }; |
254 | } |
139 | 255 |