简体   繁体   English

如何在python中强加总位数(新格式)

[英]How can I impose the total number of digits in python (new formatting)

I would like to keep the total number of digits (before and after the decimal point) of a float constant in python. 我想在python中保持float常量的总位数(小数点前后)。

For example, if I want to impose a fixed width of 7: 1234.567890123 would become 1234.567 but 12345.678901234 would become 12345.67 例如,如果我想强加固定宽度7:1234.567890123将变为1234.567但12345.678901234将变为12345.67

Fixing the number of decimals does not work in this case since it depends on how many digits I have before the decimal point. 在这种情况下,修复小数位数不起作用,因为它取决于我在小数点之前有多少位数。 I also tried the [width] option but it impose a minimum width and I need a maximum. 我也尝试了[width]选项,但它施加了最小宽度,我需要一个最大值。

Thanks for your input! 感谢您的输入!

Just by using your example, 只是用你的例子,

a = 1234.567890123 
b = 12345.678901234
str(a)[:8] # gives '1234.567'
str(b)[:8] # gives '12345.67'

The simplest solution is probably to use the exponential format with one less than the number of digits. 最简单的解决方案可能是使用指数格式,其中一个小于位数。

"{0:.6e}".format(1234.457890123) = '1.234568e+03'

I ended up writing this solution that can print floats as well as exponentials but it's probably unnecessarily long for most needs. 我最终编写了这个可以打印浮点数和指数的解决方案,但对于大多数需求来说,这可能是不必要的。

 import numpy as np

 def sigprint(number,nsig):
     """
     Returns a string with the given number of significant digits.
     For numbers >= 1e5, and less than 0.001, it does exponential notation
     This is almost what ":.3g".format(x) does, but in the case
     of '{:.3g}'.format(2189), we want 2190 not 2.19e3. Also in the case of
     '{:.3g}'.format(1), we want 1.00, not 1
     """

     if ((abs(number) >= 1e-3) and (abs(number) < 1e5)) or number ==0:
         place = decplace(number) - nsig + 1
         decval = 10**place
         outnum = np.round(np.float(number) / decval) * decval
         ## Need to get the place again in case say 0.97 was rounded up to 1.0
         finalplace = decplace(outnum) - nsig + 1 
         if finalplace >= 0: finalplace=0
         fmt='.'+str(int(abs(finalplace)))+'f'
     else:
         stringnsig = str(int(nsig-1))
         fmt = '.'+stringnsig+'e'
         outnum=number
     wholefmt = "{0:"+fmt+"}"

     return wholefmt.format(outnum)

 def decplace(number):
     """
     Finds the decimal place of the leading digit of a number. For 0, it assumes
     a value of 0 (the one's digit)
     """
     if number == 0:
         place = 0
     else:
         place = np.floor(np.log10(np.abs(number)))
     return place

You can set the precision when using decimal 您可以在使用小数时设置精度

It sounds like you also want to round down, but could choose other rounding options if you like. 听起来你也想要向下舍入,但如果你愿意,可以选择其他的舍入选项。 You create a context that includes the precision, rounding logic, and a few other options. 您可以创建包含精度,舍入逻辑和一些其他选项的上下文。 You can apply the context to all future operations with setcontext , a single number using normalize , or with a context manager using localcontext . 您可以使用setcontext将上下文应用于所有将来的操作,使用normalize将单个数字localcontext使用localcontext的上下文管理器。

import decimal
ctx = decimal.Context(prec=7, rounding=decimal.ROUND_DOWN)
print(decimal.Decimal.from_float(1234.567890123).normalize(ctx))
print(decimal.Decimal.from_float(12345.678901234).normalize(ctx))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM