Skip to content

Commit dfc8233

Browse files
committed
Handle underscores in float literals
1 parent 2c31003 commit dfc8233

File tree

1 file changed

+44
-11
lines changed

1 file changed

+44
-11
lines changed

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

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,8 @@ private double convertStringToDoubleOrThrow(String str) throws NumberFormatExcep
10271027
StringBuilder s = null;
10281028
int n = str.length();
10291029

1030+
boolean containsUnderscores = false;
1031+
boolean containsN = false;
10301032
for (int i = 0; i < n; i++) {
10311033
char ch = str.charAt(i);
10321034
if (ch == '\u0000' || ch == 'x' || ch == 'X') {
@@ -1045,21 +1047,52 @@ private double convertStringToDoubleOrThrow(String str) throws NumberFormatExcep
10451047
}
10461048
s.setCharAt(i, ' ');
10471049
}
1048-
}
1049-
String sval = s != null ? s.toString() : str.trim();
1050-
String lowSval = sval.toLowerCase(Locale.ENGLISH);
1051-
if (lowSval.equals("nan") || lowSval.equals("+nan")) {
1052-
return Double.NaN;
1053-
} else if (lowSval.equals("-nan")) {
1054-
return Math.copySign(Double.NaN, -1);
1055-
} else if (lowSval.equals("inf") || lowSval.equals("+inf") || lowSval.equals("infinity") || lowSval.equals("+infinity")) {
1056-
return Double.POSITIVE_INFINITY;
1057-
} else if (lowSval.equals("-inf") || lowSval.equals("-infinity")) {
1058-
return Double.NEGATIVE_INFINITY;
1050+
containsUnderscores |= ch == '_';
1051+
containsN |= ch == 'n' || ch == 'N';
1052+
}
1053+
String sval = s != null ? s.toString().trim() : str;
1054+
if (containsUnderscores) {
1055+
sval = checkAndRemoveUnderscores(sval);
1056+
}
1057+
if (containsN) {
1058+
String lowSval = sval.toLowerCase(Locale.ENGLISH);
1059+
if (lowSval.equals("nan") || lowSval.equals("+nan")) {
1060+
return Double.NaN;
1061+
} else if (lowSval.equals("-nan")) {
1062+
return Math.copySign(Double.NaN, -1);
1063+
} else if (lowSval.equals("inf") || lowSval.equals("+inf") || lowSval.equals("infinity") || lowSval.equals("+infinity")) {
1064+
return Double.POSITIVE_INFINITY;
1065+
} else if (lowSval.equals("-inf") || lowSval.equals("-infinity")) {
1066+
return Double.NEGATIVE_INFINITY;
1067+
}
10591068
}
10601069
return Double.parseDouble(sval);
10611070
}
10621071

1072+
private static String checkAndRemoveUnderscores(String src) {
1073+
StringBuilder sb = new StringBuilder();
1074+
char prev = 0;
1075+
int len = src.length();
1076+
for (int i = 0; i < len; i++) {
1077+
char ch = src.charAt(i);
1078+
if (ch == '_') {
1079+
if (!(prev >= '0' && prev <= '9')) {
1080+
throw new NumberFormatException();
1081+
}
1082+
} else {
1083+
if (prev == '_' && !(ch >= '0' && ch <= '9')) {
1084+
throw new NumberFormatException();
1085+
}
1086+
sb.append(ch);
1087+
}
1088+
prev = ch;
1089+
}
1090+
if (prev == '_') {
1091+
throw new NumberFormatException();
1092+
}
1093+
return sb.toString();
1094+
}
1095+
10631096
@Specialization(guards = "!isNativeClass(cls)")
10641097
Object floatFromNone(Object cls, @SuppressWarnings("unused") PNone arg) {
10651098
if (isPrimitiveFloat(cls)) {

0 commit comments

Comments
 (0)