[Python-Dev] Two proposed changes to float formatting (original) (raw)
Terry Reedy tjreedy at udel.edu
Sun Apr 26 23:02:19 CEST 2009
- Previous message: [Python-Dev] Two proposed changes to float formatting
- Next message: [Python-Dev] Two proposed changes to float formatting
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Mark Dickinson wrote:
I'd like to propose two minor changes to float and complex formatting, for 3.1. I don't think either change should prove particularly disruptive.
(1) Currently, '%f' formatting automatically changes to '%g' formatting for numbers larger than 1e50. For example:
'%f' % 2**166. '93536104789177786765035829293842113257979682750464.000000' '%f' % 2**167. '1.87072e+50' I propose removing this feature for 3.1 More details: The current behaviour is documented (standard library->builtin types). (Until very recently, it was actually misdocumented as changing at 1e25, not 1e50.) """For safety reasons, floating point precisions are clipped to 50; %f conversions for numbers whose absolute value is over 1e50 are replaced by %g conversions. [5] All other errors raise exceptions.""" There's even a footnote: """[5] These numbers are fairly arbitrary. They are intended to avoid printing endless strings of meaningless digits without hampering correct use and without having to know the exact precision of floating point values on a particular machine.""" I don't find this particularly convincing, though---I just don't see a really good reason not to give the user exactly what she/he asks for here. I have a suspicion that at least part of the motivation for the '%f' -> '%g' switch is that it means the implementation can use a fixed-size buffer. But Eric has fixed this (in 3.1, at least) and the buffer is now dynamically allocated, so this isn't a concern any more. Other reasons not to switch from '%f' to '%g' in this way: - the change isn't gentle: as you go over the 1e50 boundary, the number of significant digits produced suddenly changes from 56 to 6;
Looking at your example, that jumped out at me as somewhat startling...
it would make more sense to me if it stayed fixed at 56 sig digits for numbers larger than 1e50.
So I agree with this, even if the default # of sig digits were less. +1
- now that we're using David Gay's 'perfect rounding' code, we can be sure that the digits aren't entirely meaningless, or at least that they're the 'right' meaningless digits. This wasn't true before. - C doesn't do this, and the %f, %g, %e formats really owe their heritage to C. - float formatting is already quite complicated enough; no need to add to the mental complexity - removal simplifies the implementation :-)
On to the second proposed change: (2) complex str and repr don't behave like float str and repr, in that the float version always adds a trailing '.0' (unless there's an exponent), but the complex version doesn't:
4., 10. (4.0, 10.0) 4. + 10.j (4+10j) I propose changing the complex str and repr to behave like the float version. That is, repr(4. + 10.j) should be "(4.0 + 10.0j)" rather than "(4+10j)". Mostly this is just about consistency, ease of implementation, and aesthetics. As far as I can tell, the extra '.0' in the float repr serves two closely-related purposes: it makes it clear to the human reader that the number is a float rather than an integer, and it makes sure that e.g., eval(repr(x)) recovers a float rather than an int. The latter point isn't a concern for the current complex repr, but the former is: 4+10j looks to me more like a Gaussian integer than a complex number.
I agree. A complex is alternately an ordered pair of floats. A different, number-theory oriented implementation of Python might even want to read 4+10j as a G. i.
tjr
- Previous message: [Python-Dev] Two proposed changes to float formatting
- Next message: [Python-Dev] Two proposed changes to float formatting
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]