C 如何事先确定无符号计算是否可能溢出?

C 如何事先确定无符号计算是否可能溢出?,c,math,arbitrary-precision,C,Math,Arbitrary Precision,作为一个个人项目,我正在为我的一个宠物项目实现一个任意精度的数字类型 我已经知道所有流行的、经过测试的、健壮的库都是这样做的。我想制定一个解决方案,作为一个自我完善的教育项目 我正在研究该区域,并试图找出是否有某种方法可以在实际计算之前大致预测某个操作是否会导致溢出。我也不太担心假阳性 我希望能够使用适合计算的最小空间。如果计算将保持在其固有范围内,我将保持在该范围内 例如:将两个64位整数相乘(如果每个整数足够大)将导致溢出。我想检测到这一点,并且仅当结果可能超过64位分辨率时,才将数字向上转

作为一个个人项目,我正在为我的一个宠物项目实现一个任意精度的数字类型

我已经知道所有流行的、经过测试的、健壮的库都是这样做的。我想制定一个解决方案,作为一个自我完善的教育项目

我正在研究该区域,并试图找出是否有某种方法可以在实际计算之前大致预测某个操作是否会导致溢出。我也不太担心假阳性

我希望能够使用适合计算的最小空间。如果计算将保持在其固有范围内,我将保持在该范围内

例如:
将两个64位整数相乘(如果每个整数足够大)将导致溢出。
我想检测到这一点,并且仅当结果可能超过64位分辨率时,才将数字向上转换为我的数字类型。在这个实验中,我将使用有符号的数字


检测溢出/下溢最明智、最有效的方法是什么?

只取两个数字中的最高位,左移一,如果这些数字的结果(例如:乘法)会导致溢出,则很有可能发生溢出

虽然它不精确,但速度非常快,并且很好地表明您需要更大的数据类型才能得到结果


这可能只适用于操作成本高昂的大型数据类型,对于简单的事情(即使是64位数字),我认为您可以依赖CPU的内置算法。。请看这个问题:

约翰·雷格尔(John Regehr)就是这么说的。

进行原始计算并检测是否发生溢出几乎总是更容易(而且通常更快)。在进行计算之前,是否有特定的原因需要检测可能性

一旦计算完成,通常很容易检测是否发生溢出。由于朴素的操作成本很低,因此如果确实发生溢出,这也不会增加计算成本,即使最终需要重做一些工作。(但是,通常情况下,您甚至不需要这样做)


这里有一个(非常)简单的例子:如果我加上两个无符号的64位数字,我可以通过比较两个加数的和来检查溢出——如果它小于溢出发生的值。因此,在计算之后检测溢出只需要一次比较(确实非常便宜)。

我从未尝试过类似的项目,所以只得到了以下问题:事先知道溢出有什么意义?较小NMBER的优化要快,还是不太明显?您需要一个精确的解决方案,或者接受一个可能会发出错误溢出警报的解决方案?您的问题和您对其中一个答案的回复都说您使用的是带符号的操作数,但标题上写的是unsigned。是哪一个?无符号算术可能更容易处理,并且可能更适合处理任意精度的数字。我将使用无符号基元类型作为基本组件进行有符号任意计算,正如在表示基址的无符号64位长数组中一样,您的示例仅在无符号操作数的情况下为真,在一般情况下不成立。并且有符号溢出的行为是未定义的。@Keith:当然对于基元类型。OP讨论的是实现任意精度类型。他需要能够处理溢出来增加表示(从而防止溢出!)。@OliCharlesworth:我想他是在问实现中使用的基本类型的溢出问题。例如,如果一个由64位数字组成的数组表示一个6400位的数字,我假设他问的是64位溢出。贾罗德,你能澄清一下吗?@OliCharlesworth:有两件事需要注意:第一,当处理任意精度的数字时,通常会分别存储一个无符号的大小和一个符号。因此,您通常只需要能够检测未签名的溢出。第二,也是更重要的一点,处理器检测有符号溢出/下溢与检测无符号溢出一样容易。目前还没有一种简单的可移植的方法来获取设置的标志,但是在任何sane平台上都可以这样做——这是处理此任务的正确方法。因为这可能会导致溢出。如果真的发生了,那就意味着你的一个数字已经很大了。