Skip to content

Commit aef4eff

Browse files
committed
Use more efficient impl for math.frexp().
1 parent af773aa commit aef4eff

1 file changed

Lines changed: 15 additions & 34 deletions

File tree

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2025, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2026, Oracle and/or its affiliates.
33
* Copyright (c) 2014, Regents of the University of California
44
*
55
* All rights reserved.
@@ -665,45 +665,26 @@ protected ArgumentClinicProvider getArgumentClinic() {
665665
@GenerateNodeFactory
666666
public abstract static class FrexpNode extends PythonUnaryClinicBuiltinNode {
667667
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};
674672
}
675673

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);
681675

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;
686681
}
687682

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);
690686

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};
707688
}
708689

709690
@Specialization

0 commit comments

Comments
 (0)