floor(a /(double)b)* b == a如果a%b == 0 in C?

时间:2014-06-21 07:27:58

标签: c floating-point

如果a和b都是整数,则想知道以下断言是否正确> 0.在这种情况下,浮点数精度会导致问题吗?

assert(a%b || floor(a/(double)b)*b==a);

2 个答案:

答案 0 :(得分:8)

如果条件的第一部分为假,则ab的倍数。

整数转换为double通常是精确的(如果double是IEEE 754的二进制64,则对于最大为2 53 的整数是精确的。假设这些条件,a/(double)bdouble最接近a的实际除以b。由于实际结果是一个低于2 53 的整数,因此它是完全可表示的,因此不会发生舍入(换句话说,浮点除法是精确的)。

floor()应用于表示整数的double,返回相同的整数。

浮点乘法与除法的原因相同,并且恰好产生a

结论:assert中的条件始终为真,ab之间的条件为-2 53 和2 53 ,对于将double实现为binary64的平台,有或没有过多的精度。

答案 1 :(得分:0)

对于64位整数,这是不正确的。右边需要对a,b是正确的,其中a是b的整数倍。如果a,b <= 2 ^ 53,那么两者都可以转换为double而没有舍入误差,a /(double)b将计算精确结果,并且一切都会好的。

但如果是&gt; 2 ^ 53,然后将a转换为double可以将结果向下舍入。然后一个/(双)b可能比精确结果小一点,floor()将它向下舍入,结果将是错误的。断言失败的一个例子是

long long a = (1LL << 53) + 1;
long long b = a / 3;

如果您使用了float,那么

断言(a%b || floor(a /(float)b)* b == a);

会因为更小的值而失败。