|
1 | 1 | /* |
2 | | - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. |
| 2 | + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. |
3 | 3 | * Copyright (c) 2014, Regents of the University of California |
4 | 4 | * |
5 | 5 | * All rights reserved. |
@@ -665,45 +665,26 @@ protected ArgumentClinicProvider getArgumentClinic() { |
665 | 665 | @GenerateNodeFactory |
666 | 666 | public abstract static class FrexpNode extends PythonUnaryClinicBuiltinNode { |
667 | 667 | public static double[] frexp(double value) { |
668 | | - // double can represent int without loss of data |
669 | | - int exponent = 0; |
670 | | - double mantissa = 0.0; |
671 | | - |
672 | | - if (value == 0.0 || value == -0.0) { |
673 | | - return new double[]{mantissa, exponent}; |
| 668 | + if (value == 0.0) { |
| 669 | + return new double[]{0.0, 0}; |
| 670 | + } else if (!Double.isFinite(value)) { |
| 671 | + return new double[]{value, -1}; |
674 | 672 | } |
675 | 673 |
|
676 | | - if (Double.isNaN(value)) { |
677 | | - mantissa = Double.NaN; |
678 | | - exponent = -1; |
679 | | - return new double[]{mantissa, exponent}; |
680 | | - } |
| 674 | + int exponent = Math.getExponent(value); |
681 | 675 |
|
682 | | - if (Double.isInfinite(value)) { |
683 | | - mantissa = value; |
684 | | - exponent = -1; |
685 | | - return new double[]{mantissa, exponent}; |
| 676 | + // Handle subnormal numbers |
| 677 | + if (exponent == Double.MIN_EXPONENT - 1) { |
| 678 | + // Scale up into the normal range |
| 679 | + double scaled = Math.scalb(value, Double.MAX_EXPONENT); |
| 680 | + exponent = Math.getExponent(scaled) - Double.MAX_EXPONENT; |
686 | 681 | } |
687 | 682 |
|
688 | | - boolean neg = false; |
689 | | - mantissa = value; |
| 683 | + // Adjust exponent so that 0.5 <= abs(mantissa) < 1 |
| 684 | + exponent += 1; |
| 685 | + double mantissa = Math.scalb(value, -exponent); |
690 | 686 |
|
691 | | - if (mantissa < 0) { |
692 | | - mantissa = -mantissa; |
693 | | - neg = true; |
694 | | - } |
695 | | - if (mantissa >= 1.0) { |
696 | | - while (mantissa >= 1) { |
697 | | - ++exponent; |
698 | | - mantissa /= 2; |
699 | | - } |
700 | | - } else if (mantissa < 0.5) { |
701 | | - while (mantissa < 0.5) { |
702 | | - --exponent; |
703 | | - mantissa *= 2; |
704 | | - } |
705 | | - } |
706 | | - return new double[]{neg ? -mantissa : mantissa, exponent}; |
| 687 | + return new double[]{mantissa, exponent}; |
707 | 688 | } |
708 | 689 |
|
709 | 690 | @Specialization |
|
0 commit comments