def round_to_nsf(value, nsf=2):
"""
Rounds the number to the provided number of significant figures.
"""
integer_part = math.floor(value)
if integer_part > 0:
integer_part_len = len(str(integer_part))
return round(value, nsf-integer_part_len)
else:
str_value = str(value)
#if of the form "8e-05"
if '-' in str_value:
index = int(str_value[str_value.find('-')+1:]) - 1
else:
st = {'1', '2', '3', '4', '5', '6', '7', '8', '9'}
index = next((i for i, ch in enumerate(str(value)) if ch in st), None) - 2
return round(value, index+nsf)
# Option 1: use math
import math
def rnd1(x, sigdig=14):
"""Round x to sigdig significant digits"""
# n = digits to the left of decimal, can be negative
n = math.floor(math.log10(abs(x))) + 1
return round(x, sigdig - n)
# Option 2: use format which also rounds
def rnd2(x, sigdig=14):
"""Round x to sigdig significant digits"""
f = f'{{:.{sigdig - 1}E}}'
s = f.format(x)
return float(s)
# Bonus: use format to truncate
def sig(x, sigdig=14):
"""Truncate x to sigdig significant digits"""
f = f'{{:.{sigdig}E}}'
s = f.format(x)
decimal= 1
minus = 1 if x < 0 else 0
s = ''.join( (s[:sigdig + minus + decimal], s[s.index('E'):]) )
return float(s)
# Unexpected format results with large number of significant digits
>>> '{:.20E}'.format(10**-1)
'1.00000000000000005551E-01'
>>> '{:.20E}'.format(10**-10)
'1.00000000000000003643E-10'
>>> '{:.20E}'.format(10**-20)
'9.99999999999999945153E-21'
>>> n = .123456789012345678901234567890
>>> '{:.20E}'.format(n)
'1.23456789012345677370E-01'
6条答案
按热度按时间d4so4syb1#
可接受的答案有局限性,在一般情况下不会产生技术上正确的有效数字。
numpy.format_float_positional直接支持所需的行为。下面的代码段返回浮点数
x
,格式为4位有效数字,不使用科学记数法。cnjp1d6j2#
为了扩展Autumn的答案,在一般情况下,可接受的答案失败的原因是
round
四舍五入到小数位,而不(必须)四舍五入到有效数字.以下函数处理小数点前后都有有效数字的情况:
虽然它 * 没有 * 解决像0.0000012345678这样的数字的情况,四舍五入到6 s.f.应该是0.00000123457。
下面的代码 * 几乎 * 可以工作--但是效率非常低,由于使用递归而有堆栈溢出的风险,并且由于计算机使用二进制算术而不是十进制算术,因此并不总是返回正确的答案:
但是我认为可以修改else子句,方法是将数字转换为字符串,在一个 * 单一 * 递归步骤中使用main函数,然后从字符串 * 构造 * 输出,以便获得一个非循环小数。
qlvxas9a3#
我假设您想四舍五入到6位有效数字。如果您想四舍五入
int
s,您可以使用结果:
w8f9ii694#
要四舍五入到目标数字,只需将数字作为负数放入四舍五入函数,然后将其转换为整数。
如果你想一直保持6位有效数字,这就是我在你的问题中看到的模式,你会想这样做:
bbuxkriu5#
扩展了@david-joy的函数。实际上,它在else子句中不能正常工作,而且实际上if子句中并没有涵盖所有的情况。下面是我的函数。
yduiuuwa6#
这些对我来说都是有效的,对于整型和浮点型,无论是正的还是负的,如果需要的话,可以通过对x应用isinstance()然后返回int()或float()来修改它们以保留原始的int或float类型。
请注意,超过14位数的格式可能会给予意外结果。