Changes in uspace/lib/softfloat/generic/comparison.c [750636a:c67aff2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/softfloat/generic/comparison.c
r750636a rc67aff2 1 1 /* 2 2 * Copyright (c) 2005 Josef Cejka 3 * Copyright (c) 2011 Petr Koupy 3 4 * All rights reserved. 4 5 * … … 30 31 * @{ 31 32 */ 32 /** @file 33 /** @file Comparison functions. 33 34 */ 34 35 35 36 #include <sftypes.h> 36 37 #include <comparison.h> 37 38 /* NaN : exp = 0xff and nonzero fraction */ 38 #include <common.h> 39 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 */ 39 47 int isFloat32NaN(float32 f) 40 48 { 49 /* NaN : exp = 0xff and nonzero fraction */ 41 50 return ((f.parts.exp == 0xFF) && (f.parts.fraction)); 42 51 } 43 52 44 /* NaN : exp = 0x7ff and nonzero fraction */ 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 */ 45 60 int isFloat64NaN(float64 d) 46 61 { 62 /* NaN : exp = 0x7ff and nonzero fraction */ 47 63 return ((d.parts.exp == 0x7FF) && (d.parts.fraction)); 48 64 } 49 65 50 /* SigNaN : exp = 0xff fraction = 0xxxxx..x (binary), where at least one x is nonzero */ 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) 74 { 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)); 78 } 79 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 */ 51 86 int isFloat32SigNaN(float32 f) 52 87 { 53 return ((f.parts.exp == 0xFF) && (f.parts.fraction < 0x400000) && (f.parts.fraction)); 54 } 55 56 /* SigNaN : exp = 0x7ff fraction = 0xxxxx..x (binary), where at least one x is nonzero */ 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)); 92 } 93 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 */ 57 100 int isFloat64SigNaN(float64 d) 58 101 { 59 return ((d.parts.exp == 0x7FF) && (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll)); 60 } 61 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 */ 62 130 int isFloat32Infinity(float32 f) 63 131 { 132 /* NaN : exp = 0x7ff and zero fraction */ 64 133 return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0)); 65 134 } 66 135 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 */ 67 142 int isFloat64Infinity(float64 d) 68 143 { 144 /* NaN : exp = 0x7ff and zero fraction */ 69 145 return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0)); 70 146 } 71 147 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 */ 72 167 int isFloat32Zero(float32 f) 73 168 { … … 75 170 } 76 171 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 */ 77 178 int isFloat64Zero(float64 d) 78 179 { … … 81 182 82 183 /** 83 * @return 1 if both floats are equal - but NaNs are not recognized 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. 84 206 */ 85 207 int isFloat32eq(float32 a, float32 b) 86 208 { 87 209 /* a equals to b or both are zeros (with any sign) */ 88 return ((a.binary==b.binary) || (((a.binary | b.binary) & 0x7FFFFFFF) == 0)); 89 } 90 91 /** 92 * @return 1 if a < b - but NaNs are not recognized 210 return ((a.binary == b.binary) || 211 (((a.binary | b.binary) & 0x7FFFFFFF) == 0)); 212 } 213 214 /** 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. 93 259 */ 94 260 int isFloat32lt(float32 a, float32 b) 95 261 { 96 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) 262 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) { 97 263 return 0; /* +- zeroes */ 264 } 98 265 99 if ((a.parts.sign) && (b.parts.sign)) 266 if ((a.parts.sign) && (b.parts.sign)) { 100 267 /* if both are negative, smaller is that with greater binary value */ 101 268 return (a.binary > b.binary); 269 } 102 270 103 /* lets negate signs - now will be positive numbers allways bigger than negative (first bit will be set for unsigned integer comparison) */ 271 /* lets negate signs - now will be positive numbers allways bigger than 272 * negative (first bit will be set for unsigned integer comparison) */ 104 273 a.parts.sign = !a.parts.sign; 105 274 b.parts.sign = !b.parts.sign; … … 108 277 109 278 /** 110 * @return 1 if a > b - but NaNs are not recognized 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. 111 341 */ 112 342 int isFloat32gt(float32 a, float32 b) 113 343 { 114 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) 344 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) { 115 345 return 0; /* zeroes are equal with any sign */ 346 } 116 347 117 if ((a.parts.sign) && (b.parts.sign)) 348 if ((a.parts.sign) && (b.parts.sign)) { 118 349 /* if both are negative, greater is that with smaller binary value */ 119 350 return (a.binary < b.binary); 351 } 120 352 121 /* lets negate signs - now will be positive numbers allways bigger than negative (first bit will be set for unsigned integer comparison) */ 353 /* lets negate signs - now will be positive numbers allways bigger than 354 * negative (first bit will be set for unsigned integer comparison) */ 122 355 a.parts.sign = !a.parts.sign; 123 356 b.parts.sign = !b.parts.sign; … … 125 358 } 126 359 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 than 379 * 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 than 411 * 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 127 417 /** @} 128 418 */
Note:
See TracChangeset
for help on using the changeset viewer.