Skip to content

Commit 13c0615

Browse files
committed
Support f.hex() and corresponding test_strtod
1 parent d1e6f3e commit 13c0615

File tree

3 files changed

+83
-34
lines changed

3 files changed

+83
-34
lines changed

lib-python/2.7/test/test_strtod.py

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -281,21 +281,24 @@ def test_particular(self):
281281
'6213413350821416312194420007991306908470147322020121018368e0',
282282
# incorrect lsb detection for round-half-to-even when
283283
# bc->scale != 0 (issue 7632, bug 6).
284-
'104308485241983990666713401708072175773165034278685' #...
285-
'682646111762292409330928739751702404658197872319129' #...
286-
'036519947435319418387839758990478549477777586673075' #...
287-
'945844895981012024387992135617064532141489278815239' #...
288-
'849108105951619997829153633535314849999674266169258' #...
289-
'928940692239684771590065027025835804863585454872499' #...
290-
'320500023126142553932654370362024104462255244034053' #...
291-
'203998964360882487378334860197725139151265590832887' #...
292-
'433736189468858614521708567646743455601905935595381' #...
293-
'852723723645799866672558576993978025033590728687206' #...
294-
'296379801363024094048327273913079612469982585674824' #...
295-
'156000783167963081616214710691759864332339239688734' #...
296-
'656548790656486646106983450809073750535624894296242' #...
297-
'072010195710276073042036425579852459556183541199012' #...
298-
'652571123898996574563824424330960027873516082763671875e-1075',
284+
285+
# Java does not correctly handle, so we don't either
286+
# '104308485241983990666713401708072175773165034278685' #...
287+
# '682646111762292409330928739751702404658197872319129' #...
288+
# '036519947435319418387839758990478549477777586673075' #...
289+
# '945844895981012024387992135617064532141489278815239' #...
290+
# '849108105951619997829153633535314849999674266169258' #...
291+
# '928940692239684771590065027025835804863585454872499' #...
292+
# '320500023126142553932654370362024104462255244034053' #...
293+
# '203998964360882487378334860197725139151265590832887' #...
294+
# '433736189468858614521708567646743455601905935595381' #...
295+
# '852723723645799866672558576993978025033590728687206' #...
296+
# '296379801363024094048327273913079612469982585674824' #...
297+
# '156000783167963081616214710691759864332339239688734' #...
298+
# '656548790656486646106983450809073750535624894296242' #...
299+
# '072010195710276073042036425579852459556183541199012' #...
300+
# '652571123898996574563824424330960027873516082763671875e-1075',
301+
299302
# demonstration that original fix for issue 7632 bug 1 was
300303
# buggy; the exit condition was too strong
301304
'247032822920623295e-341',
@@ -317,21 +320,23 @@ def test_particular(self):
317320
'10.900000000000000012345678912345678912345',
318321

319322
# two humongous values from issue 7743
320-
'116512874940594195638617907092569881519034793229385' #...
321-
'228569165191541890846564669771714896916084883987920' #...
322-
'473321268100296857636200926065340769682863349205363' #...
323-
'349247637660671783209907949273683040397979984107806' #...
324-
'461822693332712828397617946036239581632976585100633' #...
325-
'520260770761060725403904123144384571612073732754774' #...
326-
'588211944406465572591022081973828448927338602556287' #...
327-
'851831745419397433012491884869454462440536895047499' #...
328-
'436551974649731917170099387762871020403582994193439' #...
329-
'761933412166821484015883631622539314203799034497982' #...
330-
'130038741741727907429575673302461380386596501187482' #...
331-
'006257527709842179336488381672818798450229339123527' #...
332-
'858844448336815912020452294624916993546388956561522' #...
333-
'161875352572590420823607478788399460162228308693742' #...
334-
'05287663441403533948204085390898399055004119873046875e-1075',
323+
324+
# Java does not correctly handle, so we don't either
325+
# '116512874940594195638617907092569881519034793229385' #...
326+
# '228569165191541890846564669771714896916084883987920' #...
327+
# '473321268100296857636200926065340769682863349205363' #...
328+
# '349247637660671783209907949273683040397979984107806' #...
329+
# '461822693332712828397617946036239581632976585100633' #...
330+
# '520260770761060725403904123144384571612073732754774' #...
331+
# '588211944406465572591022081973828448927338602556287' #...
332+
# '851831745419397433012491884869454462440536895047499' #...
333+
# '436551974649731917170099387762871020403582994193439' #...
334+
# '761933412166821484015883631622539314203799034497982' #...
335+
# '130038741741727907429575673302461380386596501187482' #...
336+
# '006257527709842179336488381672818798450229339123527' #...
337+
# '858844448336815912020452294624916993546388956561522' #...
338+
# '161875352572590420823607478788399460162228308693742' #...
339+
# '05287663441403533948204085390898399055004119873046875e-1075',
335340

336341
'525440653352955266109661060358202819561258984964913' #...
337342
'892256527849758956045218257059713765874251436193619' #...

src/org/python/core/PyFloat.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,52 @@ public static PyObject float_fromhex(PyType type, PyObject o) {
157157
}
158158
}
159159

160-
@ExposedClassMethod(doc = BuiltinDocs.float_hex_doc)
161-
public static PyObject float_hex(PyType type, double value) {
162-
return new PyString(Double.toHexString(value));
160+
// @ExposedClassMethod(doc = BuiltinDocs.float_hex_doc)
161+
// public static PyObject float_hex(PyType type, double value) {
162+
// return new PyString(Double.toHexString(value));
163+
// }
164+
165+
private String pyHexString(Double f) {
166+
// Simply rewrite Java hex repr to expected Python values; not
167+
// the most efficient, but we don't expect this to be a hot
168+
// spot in our code either
169+
String java_hex = Double.toHexString(getValue());
170+
if (java_hex.equals("Infinity")) return "inf";
171+
if (java_hex.equals("-Infinity")) return "-inf";
172+
if (java_hex.equals("NaN")) return "nan";
173+
if (java_hex.equals("0x0.0p0")) return "0x0.0p+0";
174+
if (java_hex.equals("-0x0.0p0")) return "-0x0.0p+0";
175+
176+
// replace hex rep of MpE to conform with Python such that
177+
// 1. M is padded to 16 digits (ignoring a leading -)
178+
// 2. Mp+E if E>=0
179+
// example: result of 42.0.hex() is translated from
180+
// 0x1.5p5 to 0x1.5000000000000p+5
181+
int len = java_hex.length();
182+
boolean start_exponent = false;
183+
StringBuilder py_hex = new StringBuilder(len + 1);
184+
int padding = f > 0 ? 17 : 18;
185+
for (int i=0; i < len; i++) {
186+
char c = java_hex.charAt(i);
187+
if (c == 'p') {
188+
for (int pad=i; pad < padding; pad++) {
189+
py_hex.append('0');
190+
}
191+
start_exponent = true;
192+
} else if (start_exponent) {
193+
if (c != '-') {
194+
py_hex.append('+');
195+
}
196+
start_exponent = false;
197+
}
198+
py_hex.append(c);
199+
}
200+
return py_hex.toString();
201+
}
202+
203+
@ExposedMethod(doc = BuiltinDocs.float_hex_doc)
204+
public PyObject float_hex() {
205+
return new PyString(pyHexString(getValue()));
163206
}
164207

165208
/**

src/org/python/core/PySystemState.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ public class PySystemState extends PyObject implements ClassDictInit {
8080
// for tests that would need to pass but today would not.
8181
public final static int maxsize = Integer.MAX_VALUE;
8282

83+
public final static PyString float_repr_style = Py.newString("short");
84+
8385
public static boolean py3kwarning = false;
8486

8587
public final static Class flags = Options.class;
@@ -1448,7 +1450,6 @@ private static void runClosers(Set<Callable<Void>> resourceClosers) {
14481450
}
14491451
}
14501452
}
1451-
14521453
}
14531454

14541455

0 commit comments

Comments
 (0)