| @@ 640-686 (lines=47) @@ | ||
| 637 | return Integer(total) |
|
| 638 | ||
| 639 | ||
| 640 | class Multiply(Function): |
|
| 641 | def call(self, args): |
|
| 642 | float_args = False |
|
| 643 | fraction_args = False |
|
| 644 | ||
| 645 | for arg in args: |
|
| 646 | if isinstance(arg, Integer): |
|
| 647 | pass |
|
| 648 | elif isinstance(arg, Fraction): |
|
| 649 | fraction_args = True |
|
| 650 | elif isinstance(arg, Float): |
|
| 651 | float_args = True |
|
| 652 | else: |
|
| 653 | return TrifleExceptionInstance( |
|
| 654 | wrong_type, |
|
| 655 | u"* requires numbers, but got: %s." % arg.repr()) |
|
| 656 | ||
| 657 | args = coerce_numbers(args) |
|
| 658 | ||
| 659 | if float_args: |
|
| 660 | product = 1.0 |
|
| 661 | for arg in args: |
|
| 662 | product *= arg.float_value |
|
| 663 | ||
| 664 | return Float(product) |
|
| 665 | ||
| 666 | elif fraction_args: |
|
| 667 | product = Fraction(RBigInt.fromint(1), RBigInt.fromint(1)) |
|
| 668 | ||
| 669 | for arg in args: |
|
| 670 | product = Fraction( |
|
| 671 | product.numerator.mul(arg.numerator), |
|
| 672 | product.denominator.mul(arg.denominator), |
|
| 673 | ) |
|
| 674 | ||
| 675 | # TODO: It would be convenient to have RBIGINT_ZERO and RBIGINT_ONE |
|
| 676 | # even if we don't cache small numbers the way Python does. |
|
| 677 | if product.denominator.eq(RBigInt.fromint(1)): |
|
| 678 | return Integer(product.numerator) |
|
| 679 | ||
| 680 | return product |
|
| 681 | ||
| 682 | else: |
|
| 683 | product = RBigInt.fromint(1) |
|
| 684 | for arg in args: |
|
| 685 | product = product.mul(arg.bigint_value) |
|
| 686 | return Integer(product) |
|
| 687 | ||
| 688 | ||
| 689 | class Divide(Function): |
|
| @@ 531-577 (lines=47) @@ | ||
| 528 | return nums |
|
| 529 | ||
| 530 | ||
| 531 | class Add(Function): |
|
| 532 | def call(self, args): |
|
| 533 | float_args = False |
|
| 534 | fraction_args = False |
|
| 535 | ||
| 536 | for arg in args: |
|
| 537 | if isinstance(arg, Integer): |
|
| 538 | pass |
|
| 539 | elif isinstance(arg, Fraction): |
|
| 540 | fraction_args = True |
|
| 541 | elif isinstance(arg, Float): |
|
| 542 | float_args = True |
|
| 543 | else: |
|
| 544 | return TrifleExceptionInstance( |
|
| 545 | wrong_type, |
|
| 546 | u"+ requires numbers, but got: %s." % arg.repr()) |
|
| 547 | ||
| 548 | args = coerce_numbers(args) |
|
| 549 | ||
| 550 | if float_args: |
|
| 551 | total = 0.0 |
|
| 552 | for arg in args: |
|
| 553 | total += arg.float_value |
|
| 554 | ||
| 555 | return Float(total) |
|
| 556 | ||
| 557 | elif fraction_args: |
|
| 558 | total = Fraction(RBigInt.fromint(0), RBigInt.fromint(1)) |
|
| 559 | ||
| 560 | for arg in args: |
|
| 561 | # a/b + c/d == (ad + bc) / bd |
|
| 562 | total = Fraction( |
|
| 563 | total.numerator.mul(arg.denominator).add(arg.numerator.mul(total.denominator)), |
|
| 564 | arg.denominator.mul(total.denominator) |
|
| 565 | ) |
|
| 566 | ||
| 567 | if total.denominator.eq(RBigInt.fromint(1)): |
|
| 568 | return Integer(total.numerator) |
|
| 569 | ||
| 570 | return total |
|
| 571 | ||
| 572 | else: |
|
| 573 | # Just integers. |
|
| 574 | total = RBigInt.fromint(0) |
|
| 575 | for arg in args: |
|
| 576 | total = total.add(arg.bigint_value) |
|
| 577 | return Integer(total) |
|
| 578 | ||
| 579 | ||
| 580 | class Subtract(Function): |
|