Search code examples
pythondecimalieee-754significant-digits

Why doesn't python decimal library return the specified number of signficant figures for some inputs


NB: this question is about significant figures. It is not a question about "digits after the decimal point" or anything like that.

EDIT: This question is not a duplicate of Significant figures in the decimal module. The two questions are asking about entirely different problems. I want to know why the function about does not return the desired value for a specific input. None of the answers to Significant figures in the decimal module address this question.


The following function is supposed to return a string representation of a float with the specified number of significant figures:

import decimal

def to_sigfigs(value, sigfigs):
    return str(decimal.Context(prec=sigfigs).create_decimal(value))

At first glance, it seems to work:

print to_sigfigs(0.000003141592653589793, 5)
# 0.0000031416

print to_sigfigs(0.000001, 5)
# 0.0000010000

print to_sigfigs(3.141592653589793, 5)
# 3.1416

...but

print to_sigfigs(1.0, 5)
# 1

The desired output for the last expression (IOW, the 5-significant figure representation of 1.0) is the string '1.0000'. The actual output is the string '1'.

Am I misunderstanding something or is this a bug in decimal?


Solution

  • Is it a bug? I don't know, I don't think the documentation is tight enough to make that determination. It certainly is a surprising result.

    It is possible to fix your own function with a little more logic.

    def to_sigfigs(value, sigfigs):
        sign, digits, exponent = decimal.Context(prec=sigfigs).create_decimal(value).as_tuple()
        if len(digits) < sigfigs:
            missing = sigfigs - len(digits)
            digits = digits + (0,) * missing
            exponent -= missing
        return str(decimal.Decimal((sign, digits, exponent)))