Was I being that obtuse? Of course floats are not real numbers, nor are they decimal numbers – that’s been hashed out TO DEATH in this thread and many others.
But the fact remains that as much as everyone tells us “that’s not what you want”, and “what you want is not possible with floats” – it IS still useful. At least to me, and presumably to the very many people that ask about this, and post solutions on stack overflow, etc, etc, etc. Sure, some of those folks may misunderstand what they are getting, but many of us don’t misunderstand, we just still find it useful (and yes, I have one in my personal toolbox).
The reason I posted the round()
example is to make the point that round()
has exactly the same issues as a “round to significant figures” function would have, and it’s been in the stdlib since the beginning, and in the C math lib, and probably every other language’s (certainly most) math libs.
As a science guy, I’m still very surprised that it’s not a standard feature of math libraries.
Chris A: Please don’t make the argument that because you don’t use something, that means no one else should have a need for it. We all are solving different problems.
I think these are facts:
- A properly written floating point round_to_significant_figures function has all the issues, but no more, than most other float functions, specifically
round()
, It is no more nor less abusable or confusing than many other floating point operations.
- It is asked for quite often, to the point where there are a lot of discussions / solutions, etc. on stackoverflow and the like, and indeed, on python forums like this one.
- It is not so trivial that we should expect everyone to just write that one-liner themselves – there are a lot of not-great solutions out there, including in this very thread.
- But it IS a one (or few) liner, so it’s a bit silly to put it on PyPi – leftpad anyone?
All that leads me to think it would be a good candidate for the stdlib math module.
@pf_moore suggested that this is a small enough thing to not need a PEP (i agree), so maybe the next step is a PR, and let the core devs decide. I think that’s a fine idea, but I don’t know that I want to put the time in to write a PR (and the math lib is written in C, so not that trivial) if it’s simply going to get rejected outright. So maybe a note to the dev topic (what DO we call the “sections” on discourse?) to see if they are open to the idea is in order.
Final note: I actually agree that significant figures are mostly about “display” – at least in this case, where I’m not proposing a whole system for tracking precision. However, that doesn’t mean that you should have to do string formatting to get it. Python is very nice in that the float __str__
(and __repr__
) will show you only as many decimal digits as it needs to get “as close as you can” [*] to the underlying binary value. So in practice, if you round a float to a certain number of decimal digits, and display it with anything that uses the string representation, then it will work as expected – and this is, in fact, quite useful:
- you don’t need to use formatting, and remember the format specifier you need to simply print the number, or write it to a file, or …
- You don’t need to do anything fancy to control how some other library will convert it to a string:
A recent example of mine: I need to write floating point values to JSON (yes, to later be displayed in a Web UI) – and I really didn’t want tp put a full 15 digits into the JSON. Turns out if I round to sig figs first, then the JSON lib simply does the right thing – so yes, it’s display (or conversion to strings), but no, I don’t want to have to do that string conversion myself:
In [68]: json.dumps(a)
Out[68]: '[1234.567890123451, 0.000234567890123451, 1.23456789012345e+30, 1.23456789012345e+24]'
ugly!
In [69]: json.dumps([sigfigs(x, 3) for x in a])
Out[69]: '[1230.0, 0.000235, 1.23e+30, 1.23e+24]'
Nice!
And oh so much easier than trying to control how the JSON is written.
[*] honestly, I’m not sure of the algorithm or the precise definition, but for practical purposes it works as expected.