[Tutor] Rounding to n significant digits?
Tim Peters
tim.peters at gmail.com
Sat Jul 3 15:49:09 EDT 2004
[Dick Moores]
...
> But I realize that I don't need to return a float. Just the string will
> do. Therefore, this revision of your function will do exactly what I was
> thinking of, even if I didn't say so:
>
> """
> def round_to_n(x, n):
> if n < 1:
> raise ValueError("number of significant digits must be >= 1")
> # Use %e format to get the n most significant digits, as a string.
> format = "%." + str(n-1) + "e"
> as_string = format % x
> return as_string
> """
> print round_to_n(123.456789, 4)
> print round_to_n(.000000123456789, 2)
> print round_to_n(123456789, 5)
>
> That displays
>
> 1.235e+002
> 1.2e-007
> 1.2346e+008 (this is much better than getting the ".0" of 123460000.0,
> which implies accuracy to 10 significant digits instead of 5.)
Then it's time to learn about one of the more obscure features of
string formats: if you put an asterisk in a string format where a
precision specifier is expected, the actual precision to use will be
taken from the argument tuple. I realize that's confusing; that's why
I called it obscure <wink>. It should be clearer from this rewrite of
your rewrite of my original round_to_n function:
def round_to_n(x, n):
if n < 1:
raise ValueError("number of significant digits must be >= 1")
return "%.*e" % (n-1, x)
That's probably the end of the line for this problem <wink>.
A related but harder problem is to get a string rounded to n
significant digits, but where the exponent is constrained to be a
multiple of 3. This is often useful in engineering work. For
example, in computer work, 1e6 and 1e3 are natural units (mega and
kilo), but 1e4 isn't -- if I have 15,000 of something, I want to see
that as 15e3, not as 1.5e4. I don't know an easy way to get that in
Python (or in most other programming languages).
More information about the Tutor
mailing list