Changes in uspace/lib/softfloat/generic/comparison.c [c67aff2:750636a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/softfloat/generic/comparison.c
rc67aff2 r750636a 1 1 /* 2 2 * Copyright (c) 2005 Josef Cejka 3 * Copyright (c) 2011 Petr Koupy4 3 * All rights reserved. 5 4 * … … 31 30 * @{ 32 31 */ 33 /** @file Comparison functions.32 /** @file 34 33 */ 35 34 36 35 #include <sftypes.h> 37 36 #include <comparison.h> 38 #include <common.h>39 37 40 /** 41 * Determines whether the given float represents NaN (either signalling NaN or 42 * quiet NaN). 43 * 44 * @param f Single-precision float. 45 * @return 1 if float is NaN, 0 otherwise. 46 */ 38 /* NaN : exp = 0xff and nonzero fraction */ 47 39 int isFloat32NaN(float32 f) 48 40 { 49 /* NaN : exp = 0xff and nonzero fraction */50 41 return ((f.parts.exp == 0xFF) && (f.parts.fraction)); 51 42 } 52 43 53 /** 54 * Determines whether the given float represents NaN (either signalling NaN or 55 * quiet NaN). 56 * 57 * @param d Double-precision float. 58 * @return 1 if float is NaN, 0 otherwise. 59 */ 44 /* NaN : exp = 0x7ff and nonzero fraction */ 60 45 int isFloat64NaN(float64 d) 61 46 { 62 /* NaN : exp = 0x7ff and nonzero fraction */63 47 return ((d.parts.exp == 0x7FF) && (d.parts.fraction)); 64 48 } 65 49 66 /** 67 * Determines whether the given float represents NaN (either signalling NaN or 68 * quiet NaN). 69 * 70 * @param ld Quadruple-precision float. 71 * @return 1 if float is NaN, 0 otherwise. 72 */ 73 int isFloat128NaN(float128 ld) 50 /* SigNaN : exp = 0xff fraction = 0xxxxx..x (binary), where at least one x is nonzero */ 51 int isFloat32SigNaN(float32 f) 74 52 { 75 /* NaN : exp = 0x7fff and nonzero fraction */ 76 return ((ld.parts.exp == 0x7FF) && 77 !eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll)); 53 return ((f.parts.exp == 0xFF) && (f.parts.fraction < 0x400000) && (f.parts.fraction)); 78 54 } 79 55 80 /** 81 * Determines whether the given float represents signalling NaN. 82 * 83 * @param f Single-precision float. 84 * @return 1 if float is signalling NaN, 0 otherwise. 85 */ 86 int isFloat32SigNaN(float32 f) 56 /* SigNaN : exp = 0x7ff fraction = 0xxxxx..x (binary), where at least one x is nonzero */ 57 int isFloat64SigNaN(float64 d) 87 58 { 88 /* SigNaN : exp = 0xff and fraction = 0xxxxx..x (binary), 89 * where at least one x is nonzero */ 90 return ((f.parts.exp == 0xFF) && 91 (f.parts.fraction < 0x400000) && (f.parts.fraction)); 59 return ((d.parts.exp == 0x7FF) && (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll)); 92 60 } 93 61 94 /**95 * Determines whether the given float represents signalling NaN.96 *97 * @param d Double-precision float.98 * @return 1 if float is signalling NaN, 0 otherwise.99 */100 int isFloat64SigNaN(float64 d)101 {102 /* SigNaN : exp = 0x7ff and fraction = 0xxxxx..x (binary),103 * where at least one x is nonzero */104 return ((d.parts.exp == 0x7FF) &&105 (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll));106 }107 108 /**109 * Determines whether the given float represents signalling NaN.110 *111 * @param ld Quadruple-precision float.112 * @return 1 if float is signalling NaN, 0 otherwise.113 */114 int isFloat128SigNaN(float128 ld)115 {116 /* SigNaN : exp = 0x7fff and fraction = 0xxxxx..x (binary),117 * where at least one x is nonzero */118 return ((ld.parts.exp == 0x7FFF) &&119 (ld.parts.frac_hi || ld.parts.frac_lo) &&120 lt128(ld.parts.frac_hi, ld.parts.frac_lo, 0x800000000000ll, 0x0ll));121 122 }123 124 /**125 * Determines whether the given float represents positive or negative infinity.126 *127 * @param f Single-precision float.128 * @return 1 if float is infinite, 0 otherwise.129 */130 62 int isFloat32Infinity(float32 f) 131 63 { 132 /* NaN : exp = 0x7ff and zero fraction */133 64 return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0)); 134 65 } 135 66 136 /**137 * Determines whether the given float represents positive or negative infinity.138 *139 * @param d Double-precision float.140 * @return 1 if float is infinite, 0 otherwise.141 */142 67 int isFloat64Infinity(float64 d) 143 68 { 144 /* NaN : exp = 0x7ff and zero fraction */145 69 return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0)); 146 70 } 147 71 148 /**149 * Determines whether the given float represents positive or negative infinity.150 *151 * @param ld Quadruple-precision float.152 * @return 1 if float is infinite, 0 otherwise.153 */154 int isFloat128Infinity(float128 ld)155 {156 /* NaN : exp = 0x7fff and zero fraction */157 return ((ld.parts.exp == 0x7FFF) &&158 eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll));159 }160 161 /**162 * Determines whether the given float represents positive or negative zero.163 *164 * @param f Single-precision float.165 * @return 1 if float is zero, 0 otherwise.166 */167 72 int isFloat32Zero(float32 f) 168 73 { … … 170 75 } 171 76 172 /**173 * Determines whether the given float represents positive or negative zero.174 *175 * @param d Double-precision float.176 * @return 1 if float is zero, 0 otherwise.177 */178 77 int isFloat64Zero(float64 d) 179 78 { … … 182 81 183 82 /** 184 * Determines whether the given float represents positive or negative zero. 185 * 186 * @param ld Quadruple-precision float. 187 * @return 1 if float is zero, 0 otherwise. 188 */ 189 int isFloat128Zero(float128 ld) 190 { 191 uint64_t tmp_hi; 192 uint64_t tmp_lo; 193 194 and128(ld.binary.hi, ld.binary.lo, 195 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo); 196 197 return eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll); 198 } 199 200 /** 201 * Determine whether two floats are equal. NaNs are not recognized. 202 * 203 * @a First single-precision operand. 204 * @b Second single-precision operand. 205 * @return 1 if both floats are equal, 0 otherwise. 83 * @return 1 if both floats are equal - but NaNs are not recognized 206 84 */ 207 85 int isFloat32eq(float32 a, float32 b) 208 86 { 209 87 /* a equals to b or both are zeros (with any sign) */ 210 return ((a.binary == b.binary) || 211 (((a.binary | b.binary) & 0x7FFFFFFF) == 0)); 88 return ((a.binary==b.binary) || (((a.binary | b.binary) & 0x7FFFFFFF) == 0)); 212 89 } 213 90 214 91 /** 215 * Determine whether two floats are equal. NaNs are not recognized. 216 * 217 * @a First double-precision operand. 218 * @b Second double-precision operand. 219 * @return 1 if both floats are equal, 0 otherwise. 220 */ 221 int isFloat64eq(float64 a, float64 b) 222 { 223 /* a equals to b or both are zeros (with any sign) */ 224 return ((a.binary == b.binary) || 225 (((a.binary | b.binary) & 0x7FFFFFFFFFFFFFFFll) == 0)); 226 } 227 228 /** 229 * Determine whether two floats are equal. NaNs are not recognized. 230 * 231 * @a First quadruple-precision operand. 232 * @b Second quadruple-precision operand. 233 * @return 1 if both floats are equal, 0 otherwise. 234 */ 235 int isFloat128eq(float128 a, float128 b) 236 { 237 uint64_t tmp_hi; 238 uint64_t tmp_lo; 239 240 /* both are zeros (with any sign) */ 241 or128(a.binary.hi, a.binary.lo, 242 b.binary.hi, b.binary.lo, &tmp_hi, &tmp_lo); 243 and128(tmp_hi, tmp_lo, 244 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo); 245 int both_zero = eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll); 246 247 /* a equals to b */ 248 int are_equal = eq128(a.binary.hi, a.binary.lo, b.binary.hi, b.binary.lo); 249 250 return are_equal || both_zero; 251 } 252 253 /** 254 * Lower-than comparison between two floats. NaNs are not recognized. 255 * 256 * @a First single-precision operand. 257 * @b Second single-precision operand. 258 * @return 1 if a is lower than b, 0 otherwise. 92 * @return 1 if a < b - but NaNs are not recognized 259 93 */ 260 94 int isFloat32lt(float32 a, float32 b) 261 95 { 262 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) {96 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) 263 97 return 0; /* +- zeroes */ 264 }265 98 266 if ((a.parts.sign) && (b.parts.sign)) {99 if ((a.parts.sign) && (b.parts.sign)) 267 100 /* if both are negative, smaller is that with greater binary value */ 268 101 return (a.binary > b.binary); 269 }270 102 271 /* lets negate signs - now will be positive numbers allways bigger than 272 * negative (first bit will be set for unsigned integer comparison) */ 103 /* lets negate signs - now will be positive numbers allways bigger than negative (first bit will be set for unsigned integer comparison) */ 273 104 a.parts.sign = !a.parts.sign; 274 105 b.parts.sign = !b.parts.sign; … … 277 108 278 109 /** 279 * Lower-than comparison between two floats. NaNs are not recognized. 280 * 281 * @a First double-precision operand. 282 * @b Second double-precision operand. 283 * @return 1 if a is lower than b, 0 otherwise. 284 */ 285 int isFloat64lt(float64 a, float64 b) 286 { 287 if (((a.binary | b.binary) & 0x7FFFFFFFFFFFFFFFll) == 0) { 288 return 0; /* +- zeroes */ 289 } 290 291 if ((a.parts.sign) && (b.parts.sign)) { 292 /* if both are negative, smaller is that with greater binary value */ 293 return (a.binary > b.binary); 294 } 295 296 /* lets negate signs - now will be positive numbers allways bigger than 297 * negative (first bit will be set for unsigned integer comparison) */ 298 a.parts.sign = !a.parts.sign; 299 b.parts.sign = !b.parts.sign; 300 return (a.binary < b.binary); 301 } 302 303 /** 304 * Lower-than comparison between two floats. NaNs are not recognized. 305 * 306 * @a First quadruple-precision operand. 307 * @b Second quadruple-precision operand. 308 * @return 1 if a is lower than b, 0 otherwise. 309 */ 310 int isFloat128lt(float128 a, float128 b) 311 { 312 uint64_t tmp_hi; 313 uint64_t tmp_lo; 314 315 or128(a.binary.hi, a.binary.lo, 316 b.binary.hi, b.binary.lo, &tmp_hi, &tmp_lo); 317 and128(tmp_hi, tmp_lo, 318 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo); 319 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) { 320 return 0; /* +- zeroes */ 321 } 322 323 if ((a.parts.sign) && (b.parts.sign)) { 324 /* if both are negative, smaller is that with greater binary value */ 325 return lt128(b.binary.hi, b.binary.lo, a.binary.hi, a.binary.lo); 326 } 327 328 /* lets negate signs - now will be positive numbers allways bigger than 329 * negative (first bit will be set for unsigned integer comparison) */ 330 a.parts.sign = !a.parts.sign; 331 b.parts.sign = !b.parts.sign; 332 return lt128(a.binary.hi, a.binary.lo, b.binary.hi, b.binary.lo); 333 } 334 335 /** 336 * Greater-than comparison between two floats. NaNs are not recognized. 337 * 338 * @a First single-precision operand. 339 * @b Second single-precision operand. 340 * @return 1 if a is greater than b, 0 otherwise. 110 * @return 1 if a > b - but NaNs are not recognized 341 111 */ 342 112 int isFloat32gt(float32 a, float32 b) 343 113 { 344 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) {114 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) 345 115 return 0; /* zeroes are equal with any sign */ 346 }347 116 348 if ((a.parts.sign) && (b.parts.sign)) {117 if ((a.parts.sign) && (b.parts.sign)) 349 118 /* if both are negative, greater is that with smaller binary value */ 350 119 return (a.binary < b.binary); 351 }352 120 353 /* lets negate signs - now will be positive numbers allways bigger than 354 * negative (first bit will be set for unsigned integer comparison) */ 121 /* lets negate signs - now will be positive numbers allways bigger than negative (first bit will be set for unsigned integer comparison) */ 355 122 a.parts.sign = !a.parts.sign; 356 123 b.parts.sign = !b.parts.sign; … … 358 125 } 359 126 360 /**361 * Greater-than comparison between two floats. NaNs are not recognized.362 *363 * @a First double-precision operand.364 * @b Second double-precision operand.365 * @return 1 if a is greater than b, 0 otherwise.366 */367 int isFloat64gt(float64 a, float64 b)368 {369 if (((a.binary | b.binary) & 0x7FFFFFFFFFFFFFFFll) == 0) {370 return 0; /* zeroes are equal with any sign */371 }372 373 if ((a.parts.sign) && (b.parts.sign)) {374 /* if both are negative, greater is that with smaller binary value */375 return (a.binary < b.binary);376 }377 378 /* lets negate signs - now will be positive numbers allways bigger than379 * negative (first bit will be set for unsigned integer comparison) */380 a.parts.sign = !a.parts.sign;381 b.parts.sign = !b.parts.sign;382 return (a.binary > b.binary);383 }384 385 /**386 * Greater-than comparison between two floats. NaNs are not recognized.387 *388 * @a First quadruple-precision operand.389 * @b Second quadruple-precision operand.390 * @return 1 if a is greater than b, 0 otherwise.391 */392 int isFloat128gt(float128 a, float128 b)393 {394 uint64_t tmp_hi;395 uint64_t tmp_lo;396 397 or128(a.binary.hi, a.binary.lo,398 b.binary.hi, b.binary.lo, &tmp_hi, &tmp_lo);399 and128(tmp_hi, tmp_lo,400 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);401 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {402 return 0; /* zeroes are equal with any sign */403 }404 405 if ((a.parts.sign) && (b.parts.sign)) {406 /* if both are negative, greater is that with smaller binary value */407 return lt128(a.binary.hi, a.binary.lo, b.binary.hi, b.binary.lo);408 }409 410 /* lets negate signs - now will be positive numbers allways bigger than411 * negative (first bit will be set for unsigned integer comparison) */412 a.parts.sign = !a.parts.sign;413 b.parts.sign = !b.parts.sign;414 return lt128(b.binary.hi, b.binary.lo, a.binary.hi, a.binary.lo);415 }416 417 127 /** @} 418 128 */
Note:
See TracChangeset
for help on using the changeset viewer.