this repo has no description
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