【发布时间】:2014-08-12 18:20:08
【问题描述】:
我知道如何在 Python 中对数字进行四舍五入,这不是一个简单的技术问题。
我的问题是,四舍五入会使一组百分比加起来不等于 100%,但从技术上讲,它们应该是这样的。
例如:
a = 1
b = 14
我想计算 a 在 (a + b) 中和 b 在 (a + b) 中的百分比。
答案应该是
a/(a + b) = 1/15
b/(a + b) = 14/15
当我尝试对这些数字进行四舍五入时,我得到了
1/15 = 6.66
14/15 = 93.33
(我在做地板),这使得这两个数字加起来不是 100%。
在这种情况下,我们应该为 1/15 做上限,即 6.67,为 14/15 做下限,即 93.33。现在它们加起来是 100%。这种情况下的规则应该是“四舍五入”
但是,如果我们有更复杂的情况,比如 3 个数字:
a = 1
b = 7
c = 7
地板:
1/15 = 6.66
7/15 = 46.66
7/15 = 46.66
加起来不等于 100%。
天花板:
1/15 = 6.67
7/15 = 46.67
7/15 = 46.67
加起来不等于 100%。
四舍五入(到最接近的数字)与上限相同。仍然没有达到 100%。
所以我的问题是我应该怎么做才能确保它们在任何情况下都达到 100%。
提前致谢。
更新: 感谢 cmets 的提示。我从重复的帖子答案中获取了“最大余数”解决方案。
代码是:
def round_to_100_percent(number_set, digit_after_decimal=2):
"""
This function take a list of number and return a list of percentage, which represents the portion of each number in sum of all numbers
Moreover, those percentages are adding up to 100%!!!
Notice: the algorithm we are using here is 'Largest Remainder'
The down-side is that the results won't be accurate, but they are never accurate anyway:)
"""
unround_numbers = [x / float(sum(number_set)) * 100 * 10 ** digit_after_decimal for x in number_set]
decimal_part_with_index = sorted([(index, unround_numbers[index] % 1) for index in range(len(unround_numbers))], key=lambda y: y[1], reverse=True)
remainder = 100 * 10 ** digit_after_decimal - sum([int(x) for x in unround_numbers])
index = 0
while remainder > 0:
unround_numbers[decimal_part_with_index[index][0]] += 1
remainder -= 1
index = (index + 1) % len(number_set)
return [int(x) / float(10 ** digit_after_decimal) for x in unround_numbers]
经过测试,似乎工作正常。
【问题讨论】:
-
浮点数永远不是精确的(无论是十进制还是二进制)。如果您真的需要这种准确性,请将它们存储为实际分数。另见What Every Computer Scientist Should Know About Floating-Point Arithmetic
-
不要确保它们加起来是 100%。这只是意味着通过与其他规则不同的规则对一些数字进行四舍五入。相反,如果这是为了人类可读的表示,请添加类似“由于四舍五入可能不会达到 100%”的注释,或者如果您打算使用它进行计算,请不要四舍五入。
-
@hlt,我知道这背后的原因。但是,您不认为向您的客户展示一个不等于 100% 的圆环图有点愚蠢吗?人们通常不会注意到它,开发人员甚至可以理解它,但对于真正注意到它的非技术人员来说,它会让他们觉得你不专业。 “嘿,伙计,你能把这些数字加起来 100% 吗?你知道数学吗?”。这就是这篇文章的重点。不过还是谢谢你的回复~~
-
@Cyber,那个帖子很有趣。谢谢。
-
@tobias_k,我完全同意你的观点,但我说的是解决实用问题而不是科学问题。你是对的,只要加起来达到 100%,那些人就更喜欢搞砸的数据集。没有人会尝试计算这些百分比(他们没有数据来计算),但他们只会简单地将百分比相加。连百分比都不准确(其实也没那么差)他们不会知道,但如果加起来不等于 100%,他们就会知道。