Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
3370cce4
Commit
3370cce4
authored
Apr 17, 2009
by
Mark Dickinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue 5780: Fix test_float failures for legacy style float repr.
parent
7efad9ec
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
65 additions
and
12 deletions
+65
-12
Misc/NEWS
Misc/NEWS
+4
-8
Python/pystrtod.c
Python/pystrtod.c
+61
-4
No files found.
Misc/NEWS
View file @
3370cce4
...
...
@@ -20,14 +20,7 @@ Core and Builtins
- Implement PEP 378, Format Specifier for Thousands Separator, for
floats.
- The repr function switches to exponential notation at 1e16, not 1e17
as it did before. This change applies to both 'short' and legacy
float repr styles. For the new repr style, it avoids misleading
output in some cases: an example is repr(2e16+8), which gives
'2.000000000000001e+16'; without this change it would have produced
'20000000000000010.0' instead.
- Similarly, the str function switches to exponential notation at
- The str function switches to exponential notation at
1e11, not 1e12. This avoids printing 13 significant digits in
situations where only 12 of them are correct. Example problem
value: str(1e11 + 0.5). (This minor issue has existed in 2.x for a
...
...
@@ -44,6 +37,9 @@ Core and Builtins
finite float x, repr(x) now outputs a string based on the shortest
sequence of decimal digits that rounds to x. Previous behaviour was
to output 17 significant digits and then strip trailing zeros.
Another minor difference is that the new repr switches to
exponential notation at 1e16 instead of the previous 1e17; this
avoids misleading output in some cases.
There's a new sys attribute sys.float_repr_style, which takes
the value 'short' to indicate that we're using short float repr,
...
...
Python/pystrtod.c
View file @
3370cce4
...
...
@@ -485,6 +485,50 @@ PyOS_ascii_formatd(char *buffer,
/* The fallback code to use if _Py_dg_dtoa is not available. */
/* Remove trailing zeros after the decimal point from a numeric string; also
remove the decimal point if all digits following it are zero. The numeric
string must end in '\0', and should not have any leading or trailing
whitespace. Assumes that the decimal point is '.'. */
Py_LOCAL_INLINE
(
void
)
remove_trailing_zeros
(
char
*
buffer
)
{
char
*
old_fraction_end
,
*
new_fraction_end
,
*
end
,
*
p
;
p
=
buffer
;
if
(
*
p
==
'-'
||
*
p
==
'+'
)
/* Skip leading sign, if present */
++
p
;
while
(
isdigit
(
Py_CHARMASK
(
*
p
)))
++
p
;
/* if there's no decimal point there's nothing to do */
if
(
*
p
++
!=
'.'
)
return
;
/* scan any digits after the point */
while
(
isdigit
(
Py_CHARMASK
(
*
p
)))
++
p
;
old_fraction_end
=
p
;
/* scan up to ending '\0' */
while
(
*
p
!=
'\0'
)
p
++
;
/* +1 to make sure that we move the null byte as well */
end
=
p
+
1
;
/* scan back from fraction_end, looking for removable zeros */
p
=
old_fraction_end
;
while
(
*
(
p
-
1
)
==
'0'
)
--
p
;
/* and remove point if we've got that far */
if
(
*
(
p
-
1
)
==
'.'
)
--
p
;
new_fraction_end
=
p
;
memmove
(
new_fraction_end
,
old_fraction_end
,
end
-
old_fraction_end
);
}
PyAPI_FUNC
(
char
*
)
PyOS_double_to_string
(
double
val
,
char
format_code
,
int
precision
,
...
...
@@ -498,6 +542,7 @@ PyAPI_FUNC(char *) PyOS_double_to_string(double val,
char
*
p
;
int
t
;
int
upper
=
0
;
int
strip_trailing_zeros
=
0
;
/* Validate format_code, and map upper and lower case */
switch
(
format_code
)
{
...
...
@@ -532,8 +577,17 @@ PyAPI_FUNC(char *) PyOS_double_to_string(double val,
PyErr_BadInternalCall
();
return
NULL
;
}
precision
=
12
;
format_code
=
'g'
;
/* switch to exponential notation at 1e11, or 1e12 if we're
not adding a .0 */
if
(
fabs
(
val
)
>=
(
flags
&
Py_DTSF_ADD_DOT_0
?
1e11
:
1e12
))
{
precision
=
11
;
format_code
=
'e'
;
strip_trailing_zeros
=
1
;
}
else
{
precision
=
12
;
format_code
=
'g'
;
}
break
;
default:
PyErr_BadInternalCall
();
...
...
@@ -554,11 +608,14 @@ PyAPI_FUNC(char *) PyOS_double_to_string(double val,
t
=
Py_DTST_FINITE
;
if
(
flags
&
Py_DTSF_ADD_DOT_0
)
if
(
(
flags
&
Py_DTSF_ADD_DOT_0
)
&&
(
format_code
!=
'e'
)
)
format_code
=
'Z'
;
PyOS_snprintf
(
format
,
32
,
"%%%s.%i%c"
,
(
flags
&
Py_DTSF_ALT
?
"#"
:
""
),
precision
,
format_code
);
PyOS_ascii_formatd
(
buf
,
sizeof
(
buf
),
format
,
val
);
/* remove trailing zeros if necessary */
if
(
strip_trailing_zeros
)
remove_trailing_zeros
(
buf
);
}
len
=
strlen
(
buf
);
...
...
@@ -671,7 +728,7 @@ format_float_short(double d, char format_code,
assert
(
digits_end
!=
NULL
&&
digits_end
>=
digits
);
digits_len
=
digits_end
-
digits
;
if
(
digits_len
&&
!
isdigit
(
digits
[
0
]
))
{
if
(
digits_len
&&
!
isdigit
(
Py_CHARMASK
(
digits
[
0
])
))
{
/* Infinities and nans here; adapt Gay's output,
so convert Infinity to inf and NaN to nan, and
ignore sign of nan. Then return. */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment