Determine precision and scale of particular number in Python

后端 未结 9 1916
野的像风
野的像风 2020-12-09 21:04

I have a variable in Python containing a floating point number (e.g. num = 24654.123), and I\'d like to determine the number\'s precision and scale values (in t

相关标签:
9条回答
  • 2020-12-09 21:20

    If you need to check the number of corresponding digits (of a and b)

    def prec_check(a, b):
    
      a = str(a)
      b = str(b)
      do = bool(True)
      n = 0
    
      while do == True:
    
        if a and b and a[n] == a[b]:
          n += 1
    
        else:
          do = false
    
        return n
    

    Note that this doesn't work with the "Decimal" module.

    0 讨论(0)
  • 2020-12-09 21:26

    Basically, you can't with floating point numbers. Using the decimal type would help and if you want really large precision, consider using gmpy, the GNU Multiple Precision library's port to Python.

    0 讨论(0)
  • 2020-12-09 21:30

    I found another solution that seems to be simpler, but I'm not sure exactly if it will work for all cases.

       import math
       x = 1.2345678
    
       def flip(string):
           result = ""
           for ch in string:
               result = ch + result
          return result
    
       prec = int(math.log10(float(flip(str(x)))) + 1   # precision as int
    
    0 讨论(0)
  • 2020-12-09 21:32

    Getting the number of digits to the left of the decimal point is easy:

    int(log10(x))+1
    

    The number of digits to the right of the decimal point is trickier, because of the inherent inaccuracy of floating point values. I'll need a few more minutes to figure that one out.

    Edit: Based on that principle, here's the complete code.

    import math
    
    def precision_and_scale(x):
        max_digits = 14
        int_part = int(abs(x))
        magnitude = 1 if int_part == 0 else int(math.log10(int_part)) + 1
        if magnitude >= max_digits:
            return (magnitude, 0)
        frac_part = abs(x) - int_part
        multiplier = 10 ** (max_digits - magnitude)
        frac_digits = multiplier + int(multiplier * frac_part + 0.5)
        while frac_digits % 10 == 0:
            frac_digits /= 10
        scale = int(math.log10(frac_digits))
        return (magnitude + scale, scale)
    
    0 讨论(0)
  • 2020-12-09 21:32

    I think you should consider using the decimal type instead of a float. The float type will give rounding errors because the numbers are represented internally in binary but many decimal numbers don't have an exact binary representation.

    0 讨论(0)
  • 2020-12-09 21:34

    Not possible with floating point variables. For example, typing

    >>> 10.2345
    

    gives:

    10.234500000000001
    

    So, to get 6,4 out of this, you will have to find a way to distinguish between a user entering 10.2345 and 10.234500000000001, which is impossible using floats. This has to do with the way floating point numbers are stored. Use decimal.

    import decimal
    a = decimal.Decimal('10.234539048538495')
    >>> str(a)
    '10.234539048538495'
    >>>  (len(str(a))-1, len(str(a).split('.')[1]))
    (17,15)
    
    0 讨论(0)
提交回复
热议问题