Python中实现任意精度四舍五入的高效方法

7
以下是关于以下问题的Pythonic解决方案?
我正在读取一个具有0.5分辨率的温度传感器。 我需要编写它(它具有可编程恒温器输出),同样也需要0.5的分辨率。
因此,我编写了这个函数(Python 2.7)来将输入的浮点数四舍五入到最近的0.5:
def point5res(number):
    decimals = number - int(number)
    roundnum = round(number, 0)
    return roundnum + .5 if .25 <= decimals < .75 else roundnum

print point5res (6.123)

print point5res(6.25)

print point5res(6.8)

这段代码很好,分别输出了6.0、6.5和7.0。这正是我想要的。

我在Python上还比较新手。下面这行代码:

return roundnum + .5 if .25 <= decimals < .75 else roundnum

让我对其实现者感到钦佩的流口水。但它是否符合Pythonic标准?

编辑:发布后,我了解了更多关于什么是“Pythonic”和什么不是。我的代码不符合标准。Cmd的答案如下,非常感谢!


1
尝试6.51。结果是7.5。但你说得对,链式比较是一个很棒的特性。而且三元表达式语法一旦“掌握”了,也非常好用。 - Tim Pietzcker
有些人可能嗤之以鼻,认为它不够易读,但大多数C系语言都具有三元运算符的形式。例如,在JavaScript、Java、C#等几种语言中:return 0.25 <= decimals < 0.75 ? roundnum + 0.5 : roundnum; - dwerner
@dwerner:没错,它们都有,但 && 相当于 and! 相当于 not|| 相当于 or?: 相当于 if else,就像 ugly 相当于 pretty =P。我认为这个特定的顺序(例如 1 ? 2 : 3 等同于 2 if 1 else 3)的部分原因是为了使用漂亮简短的英语单词来表示运算符。 - Claudiu
2
我认为这个问题应该重新命名为:“Python中将数字舍入到任意精度的高效方法”或类似的标题。它不是一个x或y类型的问题。 - beroe
@beroe 谢谢你的提示。我一直在想这个问题。 大家,非常感谢你们的评论。恒温器的功能是设置所需的温度。在我的情况下,这是人类在房屋中所需的温度,即永远不低于零度。(更多时在15到21度之间。)但你们说得对,对于一个“通用”的应用程序,它需要进行修订。 - RolfBly
显示剩余5条评论
2个回答

8

如果你保持表达简单,那么它们被认为是pythonic的,否则阅读起来会变得困难。

我会这样四舍五入到最近的0.5:

round(number*2) / 2.0

更加通俗易懂的表述是:“更普遍地说:”
def roundres(num, res):
    return round(num / res) * res

与原始问题所给出的示例相比,此代码未返回相同的值。它返回整数值(尝试输入6.25) - CDspace
@CDspace 原始代码存在问题,这也是为什么我发布了替代方案。同时,在浮点数上比较 == 并不会按照预期行事。 - cmd
请注意,round()在Python 2和Python 3之间的行为已发生更改。在Python 2中,round(0.5)1,而在Python 3中为0。因此,此解决方案仅适用于Python 2。这就是OP正在使用的版本,所以+1。 - Tim Pietzcker
更符合 Python 风格的做法是使用 round(number*2) / 2.0,而不是三行代码。 - Claudiu
@RolfBly:在您的意见中,这个解决方案会为哪些输入给出错误的结果? - Tim Pietzcker
显示剩余3条评论

0
return 0.5 * divmod (number, 0.5) [0] if number >= 0 else -0.5 divmod (number, -0.5) [0]

不过这看起来更漂亮:

def roundToHalf (number):
    ''' Round to nearest half '''
    half = 0.5 if number >= 0 else -0.5
    return half * divmod (number, half) [0]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接