无论使用何种数学方法,最后一位都减 1

last digit is off by 1 regardless of math methods used

这个函数的 return 值对于大参数有一个小问题(对于较小的参数工作正常)。这是代码:

def pyramid_blocks(n, m, h):
  return int(h*n*m + (h*h-h)*(3*n+3*m+2*h-1)/6)

这是失败的测试用例:

ARGUMENTS: 2123377, 2026271, 2437
EXPECTED: 10497605327499753
RETURNED: 10497605327499754

我知道公式是对的(减1会不对),但是最后一位一直四舍五入。闻起来像整数算术位问题。尝试使用 math.ceil,但仍然没有成功。

您可能打算使用整数除法:

def pyramid_blocks(n, m, h):
  return int(h*n*m + (h*h-h)*(3*n+3*m+2*h-1)//6)

整数在 Python 中是精确的。您可以使用带双斜杠的整数除法://:

def pyramid_blocks(n, m, h):
  return int(h*n*m + (h*h-h)*(3*n+3*m+2*h-1)//6)

现在这个returns10497605327499753

楼层划分(//)将解决您的问题。这只是简单地删除了小数点后的数字。

例如:

>>>20/3
>>>6.666666
>>>20//3
>>>6

更新代码:

def pyramid_blocks(n, m, h):
  return int(h*n*m + (h*h-h)*(3*n+3*m+2*h-1)//6)
pyramid_blocks(2123377,2026271,2437)

输出(对于给定的论点):

10497605327499753

第一个答案解决了问题,但如果您想知道 why this is happening:

from decimal import *
def pyramid_blocks(n, m, h):
    n = Decimal(n)
    m = Decimal(m)
    h = Decimal(h)
    return int(h*n*m + (h*h-h)*(3*n+3*m+2*h-1)/6)

pyramid_blocks(2123377,2026271,2437)

输出

10497605327499753

你的问题是除以 6,这是使用浮点运算符 /。您要使用整数除法运算符 //.

>>> n = 2123377
>>> m = 2026271
>>> h = 2437

>>> n*m*h + (h*h-h)*(3*n+3*m+2*h-1)//6
10497605327499753

关于如何解决您的问题,已经有多个答案,但还没有人回答为什么会发生这种情况。 不是整数运算,是浮点数运算!

10497605327499753 二进制是一个有 54 个二进制数字的数字。如果我们忽略留下 53 位的前导 1(它实际上并未在内存中表示)- 比 IEEE 754 double 允许的尾数(或有效数字)多一位!