0

In python, given the numbers 2.056e+07 and 2.05645e+07, how do you find each number's significant digits? That is, the length of the mantissa. The purpose is to compare numbers for data entry and only choose the one with the most information.

This information is somehow hidden in Why Are Floating Point Numbers Inaccurate? (and maybe Easy way of finding decimal places).

Using '2.05645e+07'.index('e') seems like such a hack.

Community
  • 1
  • 1
serv-inc
  • 35,772
  • 9
  • 166
  • 188

1 Answers1

0

Slightly less hackish, but still maybe improveable:

len(''.join([str(x) for x in Decimal(2.05645e+07).as_tuple().digits]).rstrip('0'))

A bit more readable with a check thanks to @Mark Dickinson

from types import StringType

def mantissa_length(string):
    '''>>> mantissa_length("2.05645e+07")
    6
    >>> mantissa_length("2.05645e+01")
    6'''
    assert type(string) is StringType, "this function fails for float values"
    digits = Decimal(string).as_tuple().digits
    return len(''.join([str(x) for x in digits]).rstrip('0'))
Community
  • 1
  • 1
serv-inc
  • 35,772
  • 9
  • 166
  • 188
  • 1
    why don't `len(str(Decimal(2.05645e+07)).rstrip('0'))` ? – itzMEonTV May 11 '17 at 10:20
  • @L_S: `len(str(Decimal(2.05645e+01)).rstrip('0'))` Good question, though. – serv-inc May 11 '17 at 10:37
  • 1
    For an input of `2.05645e+01`, your solution gives an output of `50`. Is that what you want? – Mark Dickinson May 11 '17 at 16:09
  • @MarkDickinson: curiously, this behavior is avoided if the argument is cast to a string first ... – serv-inc May 11 '17 at 17:13
  • 1
    @serv-inc: Right. With a floating-point literal, you're converting to Python's binary float format first, incurring a small rounding error, and then the conversion to Decimal is exact (and so preserves that rounding error). When converting directly from string, there's no rounding error introduced. – Mark Dickinson May 12 '17 at 07:06