this repo has no description
at trunk 1061 lines 36 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "float-builtins.h" 3 4#include <cfloat> 5#include <cmath> 6#include <limits> 7 8#include "builtins.h" 9#include "float-conversion.h" 10#include "formatter.h" 11#include "frame.h" 12#include "globals.h" 13#include "int-builtins.h" 14#include "objects.h" 15#include "runtime.h" 16#include "thread.h" 17#include "type-builtins.h" 18#include "unicode.h" 19#include "utils.h" 20 21namespace py { 22 23// Convert `object` to double. 24// Returns a NoneType and sets `value` if the conversion was successful. 25// Returns an error or unimplemented otherwise. This does specifically not 26// look for `__float__` to match the behavior of `CONVERT_TO_DOUBLE()` in 27// cpython. 28static RawObject convertToDouble(Thread* thread, const Object& object, 29 double* result) { 30 Runtime* runtime = thread->runtime(); 31 if (runtime->isInstanceOfFloat(*object)) { 32 *result = floatUnderlying(*object).value(); 33 return NoneType::object(); 34 } 35 if (runtime->isInstanceOfInt(*object)) { 36 HandleScope scope(thread); 37 Int value(&scope, intUnderlying(*object)); 38 return convertIntToDouble(thread, value, result); 39 } 40 return NotImplementedType::object(); 41} 42 43static const BuiltinAttribute kUserFloatBaseAttributes[] = { 44 {ID(_UserFloat__value), RawUserFloatBase::kValueOffset, 45 AttributeFlags::kHidden}, 46}; 47 48void initializeFloatType(Thread* thread) { 49 addBuiltinType(thread, ID(float), LayoutId::kFloat, 50 /*superclass_id=*/LayoutId::kObject, kUserFloatBaseAttributes, 51 UserFloatBase::kSize, 52 /*basetype=*/true); 53} 54 55static bool digitsFromDigitsWithUnderscores(const char* s, char* dup, 56 word* length) { 57 char* end = dup; 58 char prev = '\0'; 59 const char* p; 60 const char* last = s + *length; 61 for (p = s; p < last; p++) { 62 if (*p == '_') { 63 // Underscores are only allowed after digits. 64 if (!ASCII::isDigit(prev)) { 65 return false; 66 } 67 } else { 68 *end++ = *p; 69 // Underscores are only allowed before digits. 70 if (prev == '_' && !ASCII::isDigit(*p)) { 71 return false; 72 } 73 } 74 prev = *p; 75 } 76 // Underscores are not allowed at the end. 77 if (prev == '_') { 78 return false; 79 } 80 *end = '\0'; 81 *length = end - dup; 82 return true; 83} 84 85RawObject floatFromDigits(Thread* thread, const char* str, word length) { 86 // TODO(T57022841): follow full CPython conversion for strings 87 char* end; 88 char* new_str = nullptr; 89 const char* dup = str; 90 word dup_length = length; 91 bool release_memory = false; 92 if (std::strchr(str, '_') != nullptr) { 93 word* new_length = &dup_length; 94 release_memory = true; 95 new_str = new char[length + 1]; 96 if (!digitsFromDigitsWithUnderscores(str, new_str, new_length)) { 97 delete[] new_str; 98 return thread->raiseWithFmt(LayoutId::kValueError, 99 "could not convert string to float: '%s'", 100 str); 101 } 102 dup = new_str; 103 } 104 double result = std::strtod(dup, &end); 105 // Overflow, return infinity or negative infinity. 106 if (result == HUGE_VAL) { 107 result = std::numeric_limits<double>::infinity(); 108 } else if (result == -HUGE_VAL) { 109 result = -std::numeric_limits<double>::infinity(); 110 } else if (dup_length == 0 || end - dup != dup_length) { 111 // Conversion was incomplete; the string was not a valid float. 112 if (release_memory) { 113 delete[] new_str; 114 } 115 return thread->raiseWithFmt(LayoutId::kValueError, 116 "could not convert string to float: '%s'", str); 117 } 118 if (release_memory) { 119 delete[] new_str; 120 } 121 return thread->runtime()->newFloat(result); 122} 123 124RawObject METH(float, __abs__)(Thread* thread, Arguments args) { 125 Runtime* runtime = thread->runtime(); 126 HandleScope scope(thread); 127 Object self_obj(&scope, args.get(0)); 128 if (!runtime->isInstanceOfFloat(*self_obj)) { 129 return thread->raiseRequiresType(self_obj, ID(float)); 130 } 131 double self = floatUnderlying(*self_obj).value(); 132 return runtime->newFloat(std::fabs(self)); 133} 134 135RawObject METH(float, __bool__)(Thread* thread, Arguments args) { 136 Runtime* runtime = thread->runtime(); 137 HandleScope scope(thread); 138 Object self_obj(&scope, args.get(0)); 139 if (!runtime->isInstanceOfFloat(*self_obj)) { 140 return thread->raiseRequiresType(self_obj, ID(float)); 141 } 142 double self = floatUnderlying(*self_obj).value(); 143 return Bool::fromBool(self != 0.0); 144} 145 146RawObject METH(float, __eq__)(Thread* thread, Arguments args) { 147 HandleScope scope(thread); 148 Object self(&scope, args.get(0)); 149 Runtime* runtime = thread->runtime(); 150 if (!runtime->isInstanceOfFloat(*self)) { 151 return thread->raiseRequiresType(self, ID(float)); 152 } 153 double left = floatUnderlying(*self).value(); 154 155 Object right(&scope, args.get(1)); 156 bool result; 157 if (runtime->isInstanceOfFloat(*right)) { 158 result = left == floatUnderlying(*right).value(); 159 } else if (runtime->isInstanceOfInt(*right)) { 160 Int right_int(&scope, intUnderlying(*right)); 161 result = doubleEqualsInt(thread, left, right_int); 162 } else { 163 return NotImplementedType::object(); 164 } 165 return Bool::fromBool(result); 166} 167 168RawObject METH(float, __float__)(Thread* thread, Arguments args) { 169 HandleScope scope(thread); 170 Object self(&scope, args.get(0)); 171 if (!thread->runtime()->isInstanceOfFloat(*self)) { 172 return thread->raiseRequiresType(self, ID(float)); 173 } 174 return floatUnderlying(*self); 175} 176 177RawObject METH(float, __format__)(Thread* thread, Arguments args) { 178 HandleScope scope(thread); 179 Object self_obj(&scope, args.get(0)); 180 Runtime* runtime = thread->runtime(); 181 if (!runtime->isInstanceOfFloat(*self_obj)) { 182 return thread->raiseRequiresType(self_obj, ID(float)); 183 } 184 Object spec_obj(&scope, args.get(1)); 185 if (!runtime->isInstanceOfStr(*spec_obj)) { 186 return thread->raiseRequiresType(spec_obj, ID(str)); 187 } 188 Float self(&scope, floatUnderlying(*self_obj)); 189 Str spec(&scope, strUnderlying(*spec_obj)); 190 if (spec == Str::empty()) { 191 if (self_obj.isFloat()) { 192 unique_c_ptr<char> result( 193 doubleToString(self.value(), 'r', 0, false, true, false, nullptr)); 194 return runtime->newStrFromCStr(result.get()); 195 } 196 Object str(&scope, thread->invokeMethod1(self_obj, ID(__str__))); 197 DCHECK(!str.isErrorNotFound(), "__str__ should always exist"); 198 if (str.isErrorException()) return *str; 199 if (!runtime->isInstanceOfStr(*str)) { 200 return thread->raiseWithFmt( 201 LayoutId::kTypeError, "__str__ returned non-string (type %T)", &str); 202 } 203 return *str; 204 } 205 206 FormatSpec format; 207 Object err(&scope, parseFormatSpec(thread, spec, '\0', '>', &format)); 208 if (err.isErrorException()) { 209 return *err; 210 } 211 212 switch (format.type) { 213 case '\0': 214 case 'e': 215 case 'E': 216 case 'f': 217 case 'F': 218 case 'g': 219 case 'G': 220 case 'n': 221 case '%': 222 return formatFloat(thread, self.value(), &format); 223 default: 224 return raiseUnknownFormatError(thread, format.type, self_obj); 225 } 226} 227 228RawObject METH(float, __ge__)(Thread* thread, Arguments args) { 229 HandleScope scope(thread); 230 Object self(&scope, args.get(0)); 231 Runtime* runtime = thread->runtime(); 232 if (!runtime->isInstanceOfFloat(*self)) { 233 return thread->raiseRequiresType(self, ID(float)); 234 } 235 double left = floatUnderlying(*self).value(); 236 237 Object right(&scope, args.get(1)); 238 bool result; 239 if (runtime->isInstanceOfFloat(*right)) { 240 result = left >= floatUnderlying(*right).value(); 241 } else if (runtime->isInstanceOfInt(*right)) { 242 Int right_int(&scope, intUnderlying(*right)); 243 result = compareDoubleWithInt(thread, left, right_int, GE); 244 } else { 245 return NotImplementedType::object(); 246 } 247 return Bool::fromBool(result); 248} 249 250RawObject METH(float, __gt__)(Thread* thread, Arguments args) { 251 HandleScope scope(thread); 252 Object self(&scope, args.get(0)); 253 Runtime* runtime = thread->runtime(); 254 if (!runtime->isInstanceOfFloat(*self)) { 255 return thread->raiseRequiresType(self, ID(float)); 256 } 257 double left = floatUnderlying(*self).value(); 258 259 Object right(&scope, args.get(1)); 260 bool result; 261 if (runtime->isInstanceOfFloat(*right)) { 262 result = left > floatUnderlying(*right).value(); 263 } else if (runtime->isInstanceOfInt(*right)) { 264 Int right_int(&scope, intUnderlying(*right)); 265 result = compareDoubleWithInt(thread, left, right_int, GT); 266 } else { 267 return NotImplementedType::object(); 268 } 269 return Bool::fromBool(result); 270} 271 272void decodeDouble(double value, bool* is_neg, int* exp, int64_t* mantissa) { 273 const uint64_t man_mask = (uint64_t{1} << kDoubleMantissaBits) - 1; 274 const int num_exp_bits = kBitsPerDouble - kDoubleMantissaBits - 1; 275 const uint64_t exp_mask = (uint64_t{1} << num_exp_bits) - 1; 276 const int exp_bias = (1 << (num_exp_bits - 1)) - 1; 277 uint64_t value_bits = bit_cast<uint64_t>(value); 278 *is_neg = value_bits >> (kBitsPerDouble - 1); 279 *exp = ((value_bits >> kDoubleMantissaBits) & exp_mask) - exp_bias; 280 *mantissa = value_bits & man_mask; 281} 282 283RawObject intFromDouble(Thread* thread, double value) { 284 bool is_neg; 285 int exp; 286 int64_t man; 287 decodeDouble(value, &is_neg, &exp, &man); 288 const int exp_bits = kBitsPerDouble - kDoubleMantissaBits - 1; 289 const int max_exp = 1 << (exp_bits - 1); 290 if (exp == max_exp) { 291 if (man == 0) { 292 return thread->raiseWithFmt(LayoutId::kOverflowError, 293 "cannot convert float infinity to integer"); 294 } 295 return thread->raiseWithFmt(LayoutId::kValueError, 296 "cannot convert float NaN to integer"); 297 } 298 299 // No integral part. 300 if (exp < 0) { 301 return SmallInt::fromWord(0); 302 } 303 // Number of bits needed to represent the result integer in 2's complement. 304 // +1 for the implicit bit of value 1 and +1 for the sign bit. 305 int result_bits = exp + 2; 306 // If the number is the negative number of the greatest magnitude 307 // (-10000...b), then no extra sign bit is needed. 308 if (is_neg && man == 0) { 309 result_bits = exp + 1; 310 } 311 // Fast path for integers that are a word or smaller in size. 312 const word man_with_implicit_one = (word{1} << kDoubleMantissaBits) | man; 313 // Path that fills a digit of Int, and left-shifts it to match 314 // its magnitude with the given exponent. 315 DCHECK( 316 man_with_implicit_one >= 0, 317 "man_with_implicit_one must be positive before the sign bit is applied."); 318 Runtime* runtime = thread->runtime(); 319 if (result_bits <= kBitsPerWord) { 320 const word result = 321 (exp > kDoubleMantissaBits 322 ? (man_with_implicit_one << (exp - kDoubleMantissaBits)) 323 : (man_with_implicit_one >> (kDoubleMantissaBits - exp))); 324 return runtime->newInt(is_neg ? -result : result); 325 } 326 // TODO(djang): Make another interface for intBinaryLshift() to accept 327 // words directly. 328 HandleScope scope(thread); 329 Int unshifted_result(&scope, runtime->newInt(is_neg ? -man_with_implicit_one 330 : man_with_implicit_one)); 331 Int shifting_bits(&scope, runtime->newInt(exp - kDoubleMantissaBits)); 332 return runtime->intBinaryLshift(thread, unshifted_result, shifting_bits); 333} 334 335word doubleHash(double value) { 336 bool is_neg; 337 int exp; 338 int64_t mantissa; 339 decodeDouble(value, &is_neg, &exp, &mantissa); 340 const int exp_bits = kBitsPerDouble - kDoubleMantissaBits - 1; 341 const int max_exp = 1 << (exp_bits - 1); 342 const int min_exp = -(1 << (exp_bits - 1)) + 1; 343 344 if (exp == max_exp) { 345 word result; 346 if (mantissa == 0) { 347 result = is_neg ? -kHashInf : kHashInf; 348 } else { 349 result = kHashNan; 350 } 351 return result; 352 } 353 354 // The problem in the following is that for float numbers that compare equal 355 // to an int number, the hash values have to equal the hash values produced 356 // when hashing the integer. To achieve this we base the hashing on the same 357 // ideas as `longIntHash()`. Here we want to compute 358 // `(mantissa << (exp - mantissa_bits)) % kArithmeticHashModulus`. 359 // `mantissa` is guaranteed to be smaller than `kArithmeticHashModulus` so as 360 // explained in `longIntHash()` this just means we have to rotate it's bits by 361 // `exp` for the result. 362 363 // Add implicit one to mantissa if the number is not a subnormal. 364 if (exp > min_exp) { 365 mantissa |= int64_t{1} << kDoubleMantissaBits; 366 } else if (mantissa == 0) { 367 // Shortcut for 0.0 / -0.0. 368 return 0; 369 } else { 370 // sub-normal number, adjust exponent. 371 exp += 1; 372 } 373 374 // Compute `mantissa % kArithmeticHashModulus` which is just `mantissa`. 375 static_assert(uword{1} << (kDoubleMantissaBits + 1) < kArithmeticHashModulus, 376 "assumption `mantissa < modulus` does not hold"); 377 uword result = mantissa; 378 379 // `mantissa` represented `kDoubleMantissaBits` bits shifted by `exp`. We want 380 // to align the first integral bit to bit 0 in the result, so we have to 381 // rotate by `exp - kDoubleMantissaBits`. 382 exp -= kDoubleMantissaBits; 383 exp = exp >= 0 ? exp % kArithmeticHashBits 384 : kArithmeticHashBits - 1 - ((-1 - exp) % kArithmeticHashBits); 385 result = ((result << exp) & kArithmeticHashModulus) | 386 result >> (kArithmeticHashBits - exp); 387 388 if (is_neg) { 389 result = -result; 390 } 391 392 // cpython replaces `-1` results with -2, because -1 is used as an 393 // "uninitialized hash" marker in some situations. We do not use the same 394 // marker, but do the same to match behavior. 395 if (result == static_cast<uword>(word{-1})) { 396 result--; 397 } 398 399 // Note: We cannot cache the hash value in the object header, because the 400 // result must correspond to the hash values of SmallInt/LargeInt. The object 401 // header however has fewer bits and can only store non-negative hash codes. 402 return static_cast<word>(result); 403} 404 405RawObject METH(float, __hash__)(Thread* thread, Arguments args) { 406 HandleScope scope(thread); 407 Object self_obj(&scope, args.get(0)); 408 if (!thread->runtime()->isInstanceOfFloat(*self_obj)) { 409 return thread->raiseRequiresType(self_obj, ID(float)); 410 } 411 double self = floatUnderlying(*self_obj).value(); 412 return SmallInt::fromWord(doubleHash(self)); 413} 414 415RawObject METH(float, __int__)(Thread* thread, Arguments args) { 416 HandleScope scope(thread); 417 Object self_obj(&scope, args.get(0)); 418 if (!thread->runtime()->isInstanceOfFloat(*self_obj)) { 419 return thread->raiseRequiresType(self_obj, ID(float)); 420 } 421 double self = floatUnderlying(*self_obj).value(); 422 return intFromDouble(thread, self); 423} 424 425RawObject METH(float, __le__)(Thread* thread, Arguments args) { 426 HandleScope scope(thread); 427 Object self(&scope, args.get(0)); 428 Runtime* runtime = thread->runtime(); 429 if (!runtime->isInstanceOfFloat(*self)) { 430 return thread->raiseRequiresType(self, ID(float)); 431 } 432 double left = floatUnderlying(*self).value(); 433 434 Object right(&scope, args.get(1)); 435 bool result; 436 if (runtime->isInstanceOfFloat(*right)) { 437 result = left <= floatUnderlying(*right).value(); 438 } else if (runtime->isInstanceOfInt(*right)) { 439 Int right_int(&scope, intUnderlying(*right)); 440 result = compareDoubleWithInt(thread, left, right_int, LE); 441 } else { 442 return NotImplementedType::object(); 443 } 444 return Bool::fromBool(result); 445} 446 447RawObject METH(float, __lt__)(Thread* thread, Arguments args) { 448 HandleScope scope(thread); 449 Object self(&scope, args.get(0)); 450 Runtime* runtime = thread->runtime(); 451 if (!runtime->isInstanceOfFloat(*self)) { 452 return thread->raiseRequiresType(self, ID(float)); 453 } 454 double left = floatUnderlying(*self).value(); 455 456 Object right(&scope, args.get(1)); 457 bool result; 458 if (runtime->isInstanceOfFloat(*right)) { 459 result = left < floatUnderlying(*right).value(); 460 } else if (runtime->isInstanceOfInt(*right)) { 461 Int right_int(&scope, intUnderlying(*right)); 462 result = compareDoubleWithInt(thread, left, right_int, LT); 463 } else { 464 return NotImplementedType::object(); 465 } 466 return Bool::fromBool(result); 467} 468 469RawObject METH(float, __mul__)(Thread* thread, Arguments args) { 470 HandleScope scope(thread); 471 Object self_obj(&scope, args.get(0)); 472 Runtime* runtime = thread->runtime(); 473 if (!runtime->isInstanceOfFloat(*self_obj)) { 474 return thread->raiseRequiresType(self_obj, ID(float)); 475 } 476 double left = floatUnderlying(*self_obj).value(); 477 478 double right; 479 Object other(&scope, args.get(1)); 480 Object maybe_error(&scope, convertToDouble(thread, other, &right)); 481 // May have returned NotImplemented or raised an exception. 482 if (!maybe_error.isNoneType()) return *maybe_error; 483 484 return runtime->newFloat(left * right); 485} 486 487RawObject METH(float, __neg__)(Thread* thread, Arguments args) { 488 Runtime* runtime = thread->runtime(); 489 HandleScope scope(thread); 490 Object self_obj(&scope, args.get(0)); 491 if (!runtime->isInstanceOfFloat(*self_obj)) { 492 return thread->raiseRequiresType(self_obj, ID(float)); 493 } 494 double self = floatUnderlying(*self_obj).value(); 495 return runtime->newFloat(-self); 496} 497 498RawObject METH(float, __add__)(Thread* thread, Arguments args) { 499 HandleScope scope(thread); 500 Runtime* runtime = thread->runtime(); 501 Object self(&scope, args.get(0)); 502 if (!runtime->isInstanceOfFloat(*self)) { 503 return thread->raiseRequiresType(self, ID(float)); 504 } 505 double left = floatUnderlying(*self).value(); 506 507 double right; 508 Object other(&scope, args.get(1)); 509 Object maybe_error(&scope, convertToDouble(thread, other, &right)); 510 // May have returned NotImplemented or raised an exception. 511 if (!maybe_error.isNoneType()) return *maybe_error; 512 513 return runtime->newFloat(left + right); 514} 515 516RawObject METH(float, __truediv__)(Thread* thread, Arguments args) { 517 HandleScope scope(thread); 518 519 Object self_obj(&scope, args.get(0)); 520 Runtime* runtime = thread->runtime(); 521 if (!runtime->isInstanceOfFloat(*self_obj)) { 522 return thread->raiseRequiresType(self_obj, ID(float)); 523 } 524 double left = floatUnderlying(*self_obj).value(); 525 526 double right; 527 Object other(&scope, args.get(1)); 528 Object maybe_error(&scope, convertToDouble(thread, other, &right)); 529 // May have returned NotImplemented or raised an exception. 530 if (!maybe_error.isNoneType()) return *maybe_error; 531 532 if (right == 0.0) { 533 return thread->raiseWithFmt(LayoutId::kZeroDivisionError, 534 "float division by zero"); 535 } 536 return runtime->newFloat(left / right); 537} 538 539RawObject METH(float, __round__)(Thread* thread, Arguments args) { 540 HandleScope scope(thread); 541 Object self_obj(&scope, args.get(0)); 542 Runtime* runtime = thread->runtime(); 543 if (!runtime->isInstanceOfFloat(*self_obj)) { 544 return thread->raiseRequiresType(self_obj, ID(float)); 545 } 546 Float value_float(&scope, floatUnderlying(*self_obj)); 547 double value = value_float.value(); 548 549 // If ndigits is None round to nearest integer. 550 Object ndigits_obj(&scope, args.get(1)); 551 if (ndigits_obj.isNoneType()) { 552 double result = std::round(value); 553 // round to even. 554 if (std::fabs(value - result) == 0.5) { 555 result = 2.0 * std::round(value / 2.0); 556 } 557 return intFromDouble(thread, result); 558 } 559 560 // Round to ndigits decimals. 561 if (!runtime->isInstanceOfInt(*ndigits_obj)) { 562 return thread->raiseWithFmt(LayoutId::kTypeError, 563 "'%T' cannot be interpreted as an integer", 564 &ndigits_obj); 565 } 566 Int ndigits_int(&scope, intUnderlying(*ndigits_obj)); 567 if (ndigits_int.isLargeInt()) { 568 return ndigits_int.isNegative() ? runtime->newFloat(0.0) : *value_float; 569 } 570 word ndigits = ndigits_int.asWord(); 571 572 // Keep NaNs and infinities unchanged. 573 if (!std::isfinite(value)) { 574 return *value_float; 575 } 576 577 // Set some reasonable bounds on ndigits and clip otherwise. 578 // For `ndigits > ndigits_max`, `value` always rounds to itself. 579 // For `ndigits < ndigits_min`, `value` always rounds to +-0.0. 580 // Here 0.30103 is an upper bound for `log10(2)`. 581 static const word ndigits_max = 582 static_cast<word>((kDoubleDigits - kDoubleMinExp) * 0.30103); 583 static const word ndigits_min = 584 -static_cast<word>((kDoubleMaxExp + 1) * 0.30103); 585 if (ndigits > ndigits_max) { 586 return *value_float; 587 } 588 double result; 589 if (ndigits < ndigits_min) { 590 result = std::copysign(0.0, value); 591 } else { 592 result = doubleRoundDecimals(value, static_cast<int>(ndigits)); 593 if (result == HUGE_VAL || result == -HUGE_VAL) { 594 return thread->raiseWithFmt(LayoutId::kOverflowError, 595 "rounded value too large to represent"); 596 } 597 } 598 return runtime->newFloat(result); 599} 600 601RawObject METH(float, __rtruediv__)(Thread* thread, Arguments args) { 602 HandleScope scope(thread); 603 604 Object self_obj(&scope, args.get(0)); 605 Runtime* runtime = thread->runtime(); 606 if (!runtime->isInstanceOfFloat(*self_obj)) { 607 return thread->raiseRequiresType(self_obj, ID(float)); 608 } 609 double right = floatUnderlying(*self_obj).value(); 610 611 double left; 612 Object other(&scope, args.get(1)); 613 Object maybe_error(&scope, convertToDouble(thread, other, &left)); 614 // May have returned NotImplemented or raised an exception. 615 if (!maybe_error.isNoneType()) return *maybe_error; 616 617 if (right == 0.0) { 618 return thread->raiseWithFmt(LayoutId::kZeroDivisionError, 619 "float division by zero"); 620 } 621 return runtime->newFloat(left / right); 622} 623 624RawObject METH(float, __sub__)(Thread* thread, Arguments args) { 625 HandleScope scope(thread); 626 Object self(&scope, args.get(0)); 627 Runtime* runtime = thread->runtime(); 628 if (!runtime->isInstanceOfFloat(*self)) { 629 return thread->raiseRequiresType(self, ID(float)); 630 } 631 double left = floatUnderlying(*self).value(); 632 633 double right; 634 Object other(&scope, args.get(1)); 635 Object maybe_error(&scope, convertToDouble(thread, other, &right)); 636 // May have returned NotImplemented or raised an exception. 637 if (!maybe_error.isNoneType()) return *maybe_error; 638 639 return runtime->newFloat(left - right); 640} 641 642RawObject METH(float, __trunc__)(Thread* thread, Arguments args) { 643 HandleScope scope(thread); 644 Object self_obj(&scope, args.get(0)); 645 if (!thread->runtime()->isInstanceOfFloat(*self_obj)) { 646 return thread->raiseRequiresType(self_obj, ID(float)); 647 } 648 double self = floatUnderlying(*self_obj).value(); 649 double integral_part; 650 static_cast<void>(std::modf(self, &integral_part)); 651 return intFromDouble(thread, integral_part); 652} 653 654RawObject METH(float, __pow__)(Thread* thread, Arguments args) { 655 HandleScope scope(thread); 656 Object self(&scope, args.get(0)); 657 Runtime* runtime = thread->runtime(); 658 if (!runtime->isInstanceOfFloat(*self)) { 659 return thread->raiseRequiresType(self, ID(float)); 660 } 661 if (!args.get(2).isNoneType()) { 662 return thread->raiseWithFmt( 663 LayoutId::kTypeError, 664 "pow() 3rd argument not allowed unless all arguments are integers"); 665 } 666 double left = floatUnderlying(*self).value(); 667 668 double right; 669 Object other(&scope, args.get(1)); 670 Object maybe_error(&scope, convertToDouble(thread, other, &right)); 671 // May have returned NotImplemented or raised an exception. 672 if (!maybe_error.isNoneType()) return *maybe_error; 673 674 return runtime->newFloat(std::pow(left, right)); 675} 676 677static word nextNonHexDigit(const Str& str, word pos) { 678 for (word len = str.length(); pos < len; ++pos) { 679 if (!Byte::isHexDigit(str.byteAt(pos))) { 680 break; 681 } 682 } 683 return pos; 684} 685 686static word nextNonWhitespace(const Str& str, word pos) { 687 for (word length = str.length(); pos < length; ++pos) { 688 if (!Byte::isSpace(str.byteAt(pos))) { 689 break; 690 } 691 } 692 return pos; 693} 694 695static bool strParseOptionalSign(const Str& str, word* pos) { 696 if (*pos >= str.length()) { 697 return false; 698 } 699 700 switch (str.byteAt(*pos)) { 701 case '-': 702 ++(*pos); 703 return true; 704 case '+': 705 ++(*pos); 706 // FALLTHROUGH 707 default: 708 return false; 709 } 710} 711 712static bool strAdvancePrefixCaseInsensitiveASCII(const Str& str, word* pos, 713 const char* lowercase_prefix) { 714 // Caution: if supporting unicode, don't re-write this naively, 715 // string case operations are tricky, and locale/language 716 // dependent 717 DCHECK(pos != nullptr, "pos must be non-null"); 718 DCHECK(lowercase_prefix != nullptr, "lowercase_prefix must be non-null"); 719 720 word i = *pos; 721 word length = str.length(); 722 if (i >= length) { 723 return false; 724 } 725 726 for (; i < length && *lowercase_prefix != '\0'; ++i, ++lowercase_prefix) { 727 if (Byte::toLower(str.byteAt(i)) != *lowercase_prefix) { 728 return false; 729 } 730 } 731 // Ensure that the entire prefix was present 732 bool result = *lowercase_prefix == '\0'; 733 if (result) { 734 *pos = i; 735 } 736 return result; 737} 738 739static bool parseInfOrNan(const Str& str, word* pos, double* result) { 740 word pos_start = *pos; 741 742 bool negate = strParseOptionalSign(str, pos); 743 if (strAdvancePrefixCaseInsensitiveASCII(str, pos, "inf")) { 744 strAdvancePrefixCaseInsensitiveASCII(str, pos, "inity"); 745 *result = negate ? -kDoubleInfinity : kDoubleInfinity; 746 } else if (strAdvancePrefixCaseInsensitiveASCII(str, pos, "nan")) { 747 *result = negate ? -kDoubleNaN : kDoubleNaN; 748 } else { 749 *pos = pos_start; 750 *result = -1.0; 751 return false; 752 } 753 754 return true; 755} 756 757static RawObject newFloatOrSubclass(Thread* thread, const Type& type, 758 const Str& str, word pos, double result) { 759 // Optional trailing whitespace leading to the end of the string 760 pos = nextNonWhitespace(str, pos); 761 762 if (pos != str.length()) { 763 return thread->raiseWithFmt(LayoutId::kValueError, 764 "invalid hexadecimal floating-point string"); 765 } 766 767 if (type.instanceLayoutId() == LayoutId::kFloat) { 768 return thread->runtime()->newFloat(result); 769 } 770 771 HandleScope scope(thread); 772 Object obj(&scope, thread->runtime()->newFloat(result)); 773 return Interpreter::call1(thread, type, obj); 774} 775 776// For 0 <= i < ndigits (implicit), get_hex_digit(i) gives the jth most 777// significant digit, skipping over the '.' between integral and fractional 778// digits. 779static word getHexDigit(const Str& str, word fdigits, word coeff_end, word i) { 780 // Note: this assumes that: 781 // A) all hex digit codepoints have been previously verified to be 1 byte long 782 // B) the separating 'p' or 'P' character has been previously verified to be 1 783 // byte long. 784 word pos = i < fdigits ? coeff_end - (i) : coeff_end - 1 - i; 785 word result = Byte::toHexDigit(str.byteAt(pos)); 786 DCHECK(result >= 0, "Only hex digits should be indexed here"); 787 return result; 788} 789 790// Computes a integer float value from the digits in str via getHexDigit(), from 791// digit_ms..digit_ls, inclusive 792static double sumHexDigitsDouble(const Str& str, word fdigits, word coeff_end, 793 word digit_ms, word digit_ls) { 794 double result = 0; 795 for (word i = digit_ms; i >= digit_ls; --i) { 796 result = 16.0 * result + getHexDigit(str, fdigits, coeff_end, i); 797 } 798 return result; 799} 800 801static RawObject raiseOverflowErrorHexFloatTooLarge(Thread* thread) { 802 return thread->raiseWithFmt( 803 LayoutId::kOverflowError, 804 "hexadecimal value too large to represent as a float"); 805} 806 807static void floatHexParseCoefficients(const Str& str, word* pos, word* ndigits, 808 word* fdigits, word* coeff_end) { 809 DCHECK(pos != nullptr && ndigits != nullptr && fdigits != nullptr && 810 coeff_end != nullptr, 811 "Invalid argument to floatHexParseCoefficients"); 812 813 word coeff_start = *pos; 814 *pos = nextNonHexDigit(str, *pos); 815 816 const word length = str.length(); 817 word pos_store = *pos; 818 if (*pos < length && '.' == str.byteAt(*pos)) { 819 // Note skipping over the '.' character 820 *pos = nextNonHexDigit(str, *pos + 1); 821 *coeff_end = *pos - 1; 822 } else { 823 *coeff_end = *pos; 824 } 825 826 // ndigits = total # of hex digits; fdigits = # after point 827 *ndigits = *coeff_end - coeff_start; 828 *fdigits = *coeff_end - pos_store; 829} 830 831static long floatHexParseExponent(const Str& str, word* pos) { 832 long exponent = 0; 833 if (*pos < str.length() && 'p' == Byte::toLower(str.byteAt(*pos))) { 834 ++(*pos); 835 bool negate = strParseOptionalSign(str, pos); 836 837 for (word length = str.length(); 838 *pos < length && Byte::isDigit(str.byteAt(*pos)); ++(*pos)) { 839 exponent = exponent * 10 + Byte::toDigit(str.byteAt(*pos)); 840 } 841 if (negate) { 842 exponent = -exponent; 843 } 844 } 845 return exponent; 846} 847 848RawObject METH(float, as_integer_ratio)(Thread* thread, Arguments args) { 849 HandleScope scope(thread); 850 Object self_obj(&scope, args.get(0)); 851 Runtime* runtime = thread->runtime(); 852 if (!runtime->isInstanceOfFloat(*self_obj)) { 853 return thread->raiseRequiresType(self_obj, ID(float)); 854 } 855 Float self(&scope, floatUnderlying(*self_obj)); 856 double value = self.value(); 857 if (std::isinf(value)) { 858 return thread->raiseWithFmt(LayoutId::kOverflowError, 859 "cannot convert Infinity to integer ratio"); 860 } 861 if (std::isnan(value)) { 862 return thread->raiseWithFmt(LayoutId::kValueError, 863 "cannot convert NaN to integer ratio"); 864 } 865 int exponent; 866 double float_part = std::frexp(value, &exponent); 867 // If FLT_RADIX != 2, the 300 steps may leave a tiny fractional part to be 868 // truncated by intFromDouble. 869 for (word i = 0; i < 300 && float_part != std::floor(float_part); i++) { 870 float_part *= 2.0; 871 exponent--; 872 } 873 Object numerator_obj(&scope, intFromDouble(thread, float_part)); 874 if (numerator_obj.isErrorException()) { 875 return *numerator_obj; 876 } 877 Int numerator(&scope, *numerator_obj); 878 Int denominator(&scope, SmallInt::fromWord(1)); 879 if (exponent > 0) { 880 Int exponent_obj(&scope, SmallInt::fromWord(exponent)); 881 numerator = runtime->intBinaryLshift(thread, numerator, exponent_obj); 882 } else { 883 Int exponent_obj(&scope, SmallInt::fromWord(-exponent)); 884 denominator = runtime->intBinaryLshift(thread, denominator, exponent_obj); 885 } 886 return runtime->newTupleWith2(numerator, denominator); 887} 888 889RawObject METH(float, fromhex)(Thread* thread, Arguments args) { 890 // Convert a hexadecimal string to a float. 891 // Check the function arguments 892 HandleScope scope(thread); 893 Runtime* runtime = thread->runtime(); 894 895 Object type_obj(&scope, args.get(0)); 896 if (!runtime->isInstanceOfType(*type_obj)) { 897 return thread->raiseRequiresType(type_obj, ID(type)); 898 } 899 Type type(&scope, *type_obj); 900 901 Object str_obj(&scope, args.get(1)); 902 if (!runtime->isInstanceOfStr(*str_obj)) { 903 return thread->raiseRequiresType(str_obj, ID(str)); 904 } 905 906 const Str str(&scope, strUnderlying(*str_obj)); 907 908 // 909 // Parse the string 910 // 911 912 // leading whitespace 913 word pos = nextNonWhitespace(str, 0); 914 915 // infinities and nans 916 { 917 double result; 918 if (parseInfOrNan(str, &pos, &result)) { 919 return newFloatOrSubclass(thread, type, str, pos, result); 920 } 921 } 922 923 // optional sign 924 bool negate = strParseOptionalSign(str, &pos); 925 926 // [0x] 927 strAdvancePrefixCaseInsensitiveASCII(str, &pos, "0x"); 928 929 // coefficient: <integer> [. <fraction>] 930 word ndigits, fdigits, coeff_end; 931 floatHexParseCoefficients(str, &pos, &ndigits, &fdigits, &coeff_end); 932 if (ndigits == 0) { 933 return thread->raiseWithFmt( 934 LayoutId::kValueError, 935 "invalid hexadecimal floating-point string, no digits"); 936 } 937 938 if (ndigits > Utils::minimum(kDoubleMinExp - kDoubleDigits - kMinLong / 2, 939 kMaxLong / 2 + 1 - kDoubleMaxExp) / 940 4) { 941 return thread->raiseWithFmt(LayoutId::kValueError, 942 "hexadecimal string too long to convert"); 943 } 944 945 // [p <exponent>] 946 long exponent = floatHexParseExponent(str, &pos); 947 948 // 949 // Compute rounded value of the hex string 950 // 951 952 // Discard leading zeros, and catch extreme overflow and underflow 953 while (ndigits > 0 && 954 getHexDigit(str, fdigits, coeff_end, ndigits - 1) == 0) { 955 --ndigits; 956 } 957 if (ndigits == 0 || exponent < kMinLong / 2) { 958 return newFloatOrSubclass(thread, type, str, pos, negate ? -0.0 : 0.0); 959 } 960 if (exponent > kMaxLong / 2) { 961 return raiseOverflowErrorHexFloatTooLarge(thread); 962 } 963 964 // Adjust exponent for fractional part, 4 bits per nibble 965 exponent -= 4 * static_cast<long>(fdigits); 966 967 // top_exponent = 1 more than exponent of most sig. bit of coefficient 968 long top_exponent = exponent + 4 * (static_cast<long>(ndigits) - 1); 969 for (int digit = getHexDigit(str, fdigits, coeff_end, ndigits - 1); 970 digit != 0; digit /= 2) { 971 ++top_exponent; 972 } 973 974 // catch almost all nonextreme cases of overflow and underflow here 975 if (top_exponent < kDoubleMinExp - kDoubleDigits) { 976 return newFloatOrSubclass(thread, type, str, pos, negate ? -0.0 : 0.0); 977 } 978 if (top_exponent > kDoubleMaxExp) { 979 return raiseOverflowErrorHexFloatTooLarge(thread); 980 } 981 982 // lsb = exponent of least significant bit of the *rounded* value. 983 // This is top_exponent - kDoubleDigits unless result is subnormal. 984 long lsb = Utils::maximum(top_exponent, static_cast<long>(kDoubleMinExp)) - 985 kDoubleDigits; 986 // Check if rounding required 987 double result = 0.0; 988 if (exponent >= lsb) { 989 // no rounding required 990 result = sumHexDigitsDouble(str, fdigits, coeff_end, ndigits - 1, 0); 991 } else { 992 // rounding required. key_digit is the index of the hex digit 993 // containing the first bit to be rounded away. 994 int half_eps = 1 << static_cast<int>((lsb - exponent - 1) % 4); 995 long key_digit = (lsb - exponent - 1) / 4; 996 result = 997 sumHexDigitsDouble(str, fdigits, coeff_end, ndigits - 1, key_digit + 1); 998 999 // sum in the final key_digit, but subtract off 2*half_eps from it first to 1000 // allow for the rounding below. 1001 int digit = getHexDigit(str, fdigits, coeff_end, key_digit); 1002 result = 16.0 * result + static_cast<double>(digit & (16 - 2 * half_eps)); 1003 1004 // round-half-even: round up if bit lsb-1 is 1 and at least one of 1005 // bits lsb, lsb-2, lsb-3, lsb-4, ... is 1. 1006 if ((digit & half_eps) != 0) { 1007 bool round_up = false; 1008 if ((digit & (3 * half_eps - 1)) != 0 || 1009 (half_eps == 8 && 1010 (getHexDigit(str, fdigits, coeff_end, key_digit + 1) & 1) != 0)) { 1011 round_up = true; 1012 } else { 1013 for (ssize_t i = key_digit - 1; i >= 0; --i) { 1014 if (getHexDigit(str, fdigits, coeff_end, i) != 0) { 1015 round_up = true; 1016 break; 1017 } 1018 } 1019 } 1020 if (round_up) { 1021 result += 2 * half_eps; 1022 if (top_exponent == kDoubleMaxExp && 1023 result == ldexp(static_cast<double>(2 * half_eps), kDoubleDigits)) { 1024 // overflow corner case: pre-rounded value < 2**kDoubleMaxExp; 1025 // rounded=2**kDoubleMaxExp. 1026 return raiseOverflowErrorHexFloatTooLarge(thread); 1027 } 1028 } 1029 } 1030 // Adjust the exponent over 4 bits for every nibble we skipped processing 1031 exponent += 4 * key_digit; 1032 } 1033 result = ldexp(result, static_cast<int>(exponent)); 1034 return newFloatOrSubclass(thread, type, str, pos, negate ? -result : result); 1035} 1036 1037RawObject METH(float, hex)(Thread* thread, Arguments args) { 1038 HandleScope scope(thread); 1039 Object self(&scope, args.get(0)); 1040 Runtime* runtime = thread->runtime(); 1041 if (!runtime->isInstanceOfFloat(*self)) { 1042 return thread->raiseRequiresType(self, ID(float)); 1043 } 1044 1045 double double_value = floatUnderlying(*self).value(); 1046 return formatDoubleHexadecimalSimple(runtime, double_value); 1047} 1048 1049RawObject METH(float, is_integer)(Thread* thread, Arguments args) { 1050 HandleScope scope(thread); 1051 Object self(&scope, args.get(0)); 1052 if (!thread->runtime()->isInstanceOfFloat(*self)) { 1053 return thread->raiseRequiresType(self, ID(float)); 1054 } 1055 1056 double double_value = floatUnderlying(*self).value(); 1057 return Bool::fromBool(!std::isinf(double_value) && 1058 std::floor(double_value) == double_value); 1059} 1060 1061} // namespace py