1)这是不可溢出的吗?

long long v1, v2, result;
[..]
result = ((long double) v1 / v2) * 1000000LL;

1.a) 我可以省略常数上的 LL 吗?以及为什么。

2)或者这种没有浮动的变体可以吗?

long long l1, l2, result;
[..]
result = (1000000 * (v1 / v2) + v1 % v2);

2.a) 哪一个的管理费用更多?第一个还是这个例子?

3)浮点数是否会溢出,或者只是换行为“正常”值?

有帮助吗?

解决方案

是的,结果例(1)中可以很容易地溢出如果说,V1 =千兆和v2 = 1。你不需要对常数LL,因为它是小到足以放入一个int(下最实施方式中,在任何情况下)。

(2)即可以溢出一样好实施例1如果V1和V2作为我已经给了他们。

在第一个例子是如浮点运算比整数运算更昂贵更加昂贵。

(3)浮标可以肯定溢出和其后果是依赖于实现的。

正如Arjit所指出的,可以通过执行计算之前检查V1的值防止溢出。如果V1可以是负的,你还需要检查阴性的版本,或许下面可能会更好......

if ((LONG_LONG_MAX / 1000000) > V1)
{
...
}

如果你真的靠在限制,你可以给自己多一点的余量通过声明的变量是unsigned

后来 - 编辑以改正错误的Arjit指出

其他提示

首先

  1. 如果进行 INT 或 Long 计算,则不涉及浮点数。因为您在第一部分中的结果会有许多几乎相等的不同值。

因为 (float)v1/v2 = ab.cdef。// 其中 cdef 可以变化。

第二个实现也可能导致溢出 如果 v1 = 2^15 且 v2 = 1

因此,如果您正在寻找溢出和安全性,您应该始终检查

就像 2^18/Constant 在这种情况下是 1000000

所以

if(2^18/Constant > v1)

    result = (1000000 * (v1 / v2) + v1 % v2);

这将是任何黑客攻击的证明。

希望这可以帮助

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top