C++ c+中长整数除法的上限+;

C++ c+中长整数除法的上限+;,c++,integer,long-integer,ceil,C++,Integer,Long Integer,Ceil,我试图解决一些涉及大数划分的问题。我偶然发现了某些场景,其中我使用以下方法得到了错误的结果: LL result=(LL)ceil((double)(a-b)/c),其中a、b和c是长整数(LL) #包括/*printf*/ #包括/*ceil*/ #定义LL long long int main() { LLA=100000000000000; LL aa=1000000000000000-1; LL aaa=1000000000000000+1; int b=1; int c=1; prin

我试图解决一些涉及大数划分的问题。我偶然发现了某些场景,其中我使用以下方法得到了错误的结果:

LL result=(LL)ceil((double)(a-b)/c),其中a、b和c是长整数(LL)

#包括/*printf*/
#包括/*ceil*/
#定义LL long long
int main()
{
LLA=100000000000000;
LL aa=1000000000000000-1;
LL aaa=1000000000000000+1;
int b=1;
int c=1;
printf(“%Ld\n”,(LL)cell((double)(a-b)/c));
printf(“%Ld\n”,(LL)celi((double)(aa-b)/c));
printf(“%Ld\n”,(LL)cell((double)(aaa-b)/c));
返回0;
}
输出:
10000000000000000
9999999999999998
10000000000000000
大于或等于10^16且可被10整除的整数开始出现这种情况。
long-long的上限为~10^18。
那么是什么导致了这个错误呢


我使用的是C++14模式下的GCC 5.1(在ideone.com上)。

虽然它可以存储更大数量的数字,但典型的双精度实现只能保持15-16位左右的精度

浮点减法也可能是个问题,特别是当两个数字的大小几乎相同时。如果两个输入都是(比如)50位,但前40位是相同的,那么这些输入将抵消掉,结果将只有大约10位


因此,首先,如果你想要的结果是
long
,你可能想用它来做所有的数学运算。第二,你至少要考虑将你的<代码>(AB)/C < /代码>改为<代码> A/C-B/C < /代码>以尽可能长地延迟减法。

< P>如果你知道这两个值都是正的,你可以用纯整数(或长长)计算CEIL:

因此,在你的情况下:

    (a - b + c-1)/c

处理负数是留给读者的一个练习(它可能有点烦琐地决定你想要它做什么,而且你通常不需要它)。

你使用的是什么平台和编译器?我试用了Ideone(C++14)使用的编译器。这是代码的链接:双精度是52位=15位。@stark如果你加上这个作为答案,我会投票表决。谢谢。后来,在找出错误后,我才开始讨论这个问题。
    (x + y-1)/y
    (a - b + c-1)/c