将十进制转换为具有固定数量字符的字符串
令人惊讶的是,我似乎找不到以前回答的这个特定问题,尽管这似乎是非常标准的。
我希望能够给定长度 l ,将1e-100和1e+100(非包含)之间的任何正小数转换为具有 l 字符的字符串。我想:
- 保留尽可能多的精度数字,
- 避免添加任何额外的零(会歪曲精度),
- 避免使用指导点或尾随的小数点(例如“ .1”或“ 1”),
- 仅在科学符号中诉诸于科学符号。必要
以下是一些示例,其中 l 是10:
十进制值 | 字符串 |
---|---|
0.0000100 | 0.0000100 |
0.00001000 | 0.00001000 |
0.000010000 | Code> 1.0000E-055 |
0.123456789 | 0.12345679 |
10 | 10 |
1E+01 | 1E+01 |
100000000 | 100000000 |
100000000.0 | 100000000 |
10000000.0 | 10000000.0 |
10000000000 | 1.0000E+10 |
我能想到的最简洁的方式是:
# x is Decimal, L is length of return string
def posDecimalToString(x, L):
nDigits = significantDigits(x)
stdStr = str(x)
stdLen = len(str(x))
if (x >= 10 ** L) or (x >= 10 ** nDigits) or (stdLen - L > nDigits - (L - charsUsedByScientific(x))):
rStr = decimalToScientific(x, L)
else:
rStr = stdStr[:10]
if(rStr[-1:] == "."): rStr = rStr[:-1]
return (" " * (L - len(rStr))) + rStr
def decimalToScientific(x, L):
if significantDigits(x) > (L - charsUsedByScientific(x)):
return '{:.' + str((L - charsUsedByScientific(x)) - 1) + 'E}'.format(x)
else:
return '{:E}'.format(x)
def charsUsedByScientific(x):
sciStr = '{:E}'.format(x)
return len(sciStr) - len(sciStr[:sciStr.find('E')])
def significantDigits(x):
return len(x.as_tuple().digits)
但是对于Python来说,这似乎太长了。我认为一个问题与格式化数字一样司空见惯的问题将在某些库中具有实现。有一种更简洁的方法吗?
Surprisingly, I can't seem to find this particular question answered previously, although it seems like something that would be pretty standard.
I want to be able to, given a length L, convert any positive Decimal between 1E-100 and 1E+100 (non-inclusive) to a string with exactly L characters. I would like to:
- Preserve as many digits of precision as possible
- Avoid adding any extra zeroes (which would misrepresent the precision)
- Avoid a leading or trailing decimal point (e.g. ".1" or "1.")
- Only resort to scientific notation if necessary
Here's some examples, where L is 10:
Decimal Value | String |
---|---|
0.0000100 | 0.0000100 |
0.00001000 | 0.00001000 |
0.000010000 | 1.0000E-05 |
0.123456789 | 0.12345679 |
10 | 10 |
1E+01 | 1E+01 |
100000000 | 100000000 |
100000000.0 | 100000000 |
10000000.0 | 10000000.0 |
10000000000 | 1.0000E+10 |
The most concise way I can think of doing this is:
# x is Decimal, L is length of return string
def posDecimalToString(x, L):
nDigits = significantDigits(x)
stdStr = str(x)
stdLen = len(str(x))
if (x >= 10 ** L) or (x >= 10 ** nDigits) or (stdLen - L > nDigits - (L - charsUsedByScientific(x))):
rStr = decimalToScientific(x, L)
else:
rStr = stdStr[:10]
if(rStr[-1:] == "."): rStr = rStr[:-1]
return (" " * (L - len(rStr))) + rStr
def decimalToScientific(x, L):
if significantDigits(x) > (L - charsUsedByScientific(x)):
return '{:.' + str((L - charsUsedByScientific(x)) - 1) + 'E}'.format(x)
else:
return '{:E}'.format(x)
def charsUsedByScientific(x):
sciStr = '{:E}'.format(x)
return len(sciStr) - len(sciStr[:sciStr.find('E')])
def significantDigits(x):
return len(x.as_tuple().digits)
But this just seems far too long-winded for Python. I would think a problem as commonplace as formatting a number with precision would have an implementation in some library. Is there a more concise way to do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论