我想打印非常接近1的浮点数,并截断为两位小数,而不进行四舍五入,最好用尽量少的代码实现。
a = 0.99999999999
print(f'{a:0.2f}')
Expected: 0.99
Actual: 1.00
a = 0.99999999999
print(f'{a:0.2f}')
Expected: 0.99
Actual: 1.00
您也可以尝试这种方法,只需将数字转换为整数再转回浮点数即可截断小数部分:
num_decimals = 2
a = 0.99999999999
a = int(a * 10 ** num_decimals)/10 ** num_decimals
print(a) # => prints 0.99
如果我理解正确,我认为你不需要使用f-strings或数学函数。普通的字符串操作应该可以实现你的目标:
a = 0.987654321
print(str(a)[:4])
输出:
0.98
str(a)
会产生“1.0”。 - Eric Postpischilstr
可能会将其显示为“0.99”,然后问题中的代码就会错误地显示“0.99”而不是“0.98”。(需要注意的是,与您声称的无舍入相反,实际上确实进行了四舍五入,因为传递给它的实际浮点值不是0.987654321,而是0.98765432099999994619565768516622483730316162109375。) - Eric Postpischila = 0.87
。由于它不能被精确地保存为float
,因此使用最接近的值:0.8699999999999999955591...
。我怀疑你的str(a)
将其打印为四舍五入的17(或更少)个有效位数或0.87000000000000000
。用[:4]
截取会得到"0.87"
,而根据OP的“截断到2位小数而不进行四舍五入”,应该是"0.86"
。 - chux - Reinstate Monica0.9999999999999999
; 所以尾数被四舍五入了,但是前面一个小数点没有。 - Jack Fleetinga = 0.8699999999999999
是最长的浮点数,仍然截断为 0.86
;再加一个 9
(或任何大于 4
的数字),它就会截断为 0.87
。 - Jack Fleeting我在Python方面的技能还不够熟练,但浮点数运算与我熟悉的C语言非常接近。
Python的float
和C的double
一样是基于2进制的,所以像0.xx
这样的值,除了0.00, 0.25, 0.50, 0.75
之外,无法被准确编码。
让我们尝试a=0.87
。最接近可表示的Python float
值为:
# 1234567890123456789012
0.8699999999999999955591...
因此,真实值小于0.87。
使用少于18位数字打印(似乎是str()
的结果)会导致四舍五入的输出。
# 12345678901234567
0.87000000000000000
对文本进行截断会导致"0.87"
,并不符合“将其截断为2位小数而不四舍五入”的要求,因为原始值是0.8699999999999999955591...
要解决这个问题,代码需要在调用str()
之前更改float
数学的舍入模式以朝向0舍入而不是四舍五入或者使用额外精度转换为字符串。我怀疑Python可以做到这一点-我不确定。
即使使用额外精度(仍然使用四舍五入),在一般情况下,仍可能存在真实值为xxx.xx(很多9)...... 这会进行四舍五入并阻止我们的文本截断。
%.99g
%x),某些实现可能会正确执行此操作。但是,Python对浮点数很宽松;文档没有包含有关其特性或行为的强烈声明。是否正确实现了将多个数字转换为字符串未指定,因此不能依赖此功能。而且我认为Python没有控制舍入模式的规定。 - Eric Postpischilfloat
转换为字符串方向发展。 - chux - Reinstate Monica
math.floor()
向下取整,然后除以100。 - Barmartrunc
而不是floor
,这样也可以处理负数了?(如果输入已知接近于1且为正数,则无关紧要) - chtz