gpt4 book ai didi

c++ - 乘法溢出测试

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:22:05 36 4
gpt4 key购买 nike

<分区>

如何正确判断整数乘法是否溢出?

int i = X(), j = Y();
i *= j;

给定 ij 的值及其类型,如何检查溢出?请注意,检查必须对有符号和无符号类型都正常工作。可以假设 ij 是同一类型。还可以假设在编写代码时类型是已知的,因此可以为签名/未签名的情况提供不同的解决方案(不需要模板杂耍,如果它在“C”中工作,这是一个奖励)。

编辑:@pmg 的回答是正确的。我只是暂时无法理解它的简单性,所以我将在这里与您分享。假设我们要检查:

i * j > MAX

但我们无法真正检查,因为 i * j 会导致溢出并且结果不正确(并且总是小于或等于 MAX)。所以我们这样修改:

i > MAX / j

但这并不完全正确,因为在除法中,涉及到一些舍入。相反,我们想知道这样的结果:

i > floor(MAX / j) + float(MAX % j) / j

所以我们有除法本身,它被整数运算隐式向下舍入(floor 在那里是空操作,仅作为说明),我们有除法的余数在之前的不等式中缺失(计算结果小于 1)。

假设ij是两个达到极限的数,如果其中任何一个加1,就会发生溢出。假设它们都不为零(在这种情况下无论如何都不会发生溢出),(i + 1) * ji * (j + 1) 都更多比 1 + (i * j)。因此,我们可以安全地忽略小于 1 的除法舍入误差。

或者,我们可以这样重组:

i - floor(MAX / j) > float(MAX % j) / j

基本上,这告诉我们 i - floor(MAX/j) 必须大于 [0, 1) 区间内的数字。可以准确地写成:

i - floor(MAX / j) >= 1

因为 1 就在间隔之后。我们可以重写为:

i - floor(MAX / j) > 0

或如:

i > floor(MAX / j)

所以我们已经证明了简单测试和浮点版本的等价性。这是因为除法不会导致明显的舍入误差。我们现在可以使用简单的测试,从此过上幸福的生活。

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com