C++ 如何处理长时间的溢出
我正在使用一个API,它在long类型的变量中提供一些数据。此变量的值正在增加并将滚动多次,不幸的是,无法修改API。我试图使用类似于下面所包含的测试工具的代码来检测和补偿溢出,最终我将把数据转换为无符号long,然后转换为double:C++ 如何处理长时间的溢出,c++,C++,我正在使用一个API,它在long类型的变量中提供一些数据。此变量的值正在增加并将滚动多次,不幸的是,无法修改API。我试图使用类似于下面所包含的测试工具的代码来检测和补偿溢出,最终我将把数据转换为无符号long,然后转换为double: void DetectRolloverOneNumber(long val) { static unsigned __int64 prevVal = 0; //store value in an unsigned long unsigned long newV
void DetectRolloverOneNumber(long val)
{
static unsigned __int64 prevVal = 0;
//store value in an unsigned long
unsigned long newVal = val;
//we will eventually store in a long long
unsigned __int64 uiBigVal = newVal;
//max value for a 32 bit long
unsigned __int64 maxInt = 0xFFFFFFFF;
bool rollover = false;
//we will be adding max long + 1
maxInt++;
//detect the rollover
unsigned __int64 modVal = prevVal% maxInt;
if (newVal < modVal)
{
//account for the rollover
uiBigVal += maxInt;
rollover = true;
}
cout<< val << "\t" << newVal << "\t" << modVal << "\t" <<
uiBigVal << "\t" << prevVal << "\t" << rollover << "\n";
//cache the value so we can check for rollover next time
prevVal = uiBigVal;
到目前为止还不错,值按预期增加了100000,尽管我们通过了有符号32位长的最大值
…再往下走
-2483649 4292483647 4291483647 4292483647 4291483647
-1483649 4293483647 4292483647 4293483647 4292483647
-483649 4294483647 4293483647 4294483647 4293483647
516351 516351 4294483647 4295483647 4294483647 (rollover detected here and we are still good)
1516351 1516351 516351 1516351 4295483647
2516351 2516351 1516351 2516351 1516351 //oops!!!
3516351 3516351 2516351 3516351 2516351
所以我弄错了。有人对如何正确处理翻车有什么建议吗?
如有任何建议,将不胜感激。谢谢 只是好奇,但在你的系统上长的有多大?我猜是64位,但你的问题暗示它们是32位。此外,为什么考虑铸造双?双打没有你想象的那么大。大部分来自我使用过的系统。如果是有符号类型,则其他位用于指数和符号(我相信)。既然你使用C++,我会使用Boosi::UnTuts64来存储大数。p> 谢谢你的回答。在我的系统中,long是32位的,不幸的是,我不能使用boost,因为我在一个非常封闭的框架中工作 如前所述,我没有处理多次翻车。正如雷蒙德所说,我可以通过跟踪我以前的测试和工作记录来处理这个问题。另一种处理方法是跟踪我看到的翻车次数,执行如下操作
//the rest of the code is the same as above
if ((newVal < modVal && prevVal > 0))
{
//rollover has occurred, increment our rollover counter
rolloverCount ++;
}
//account for the rollover
uiBigVal =newVal + (maxInt * rolloverCount);
//其余代码与上面相同
if((newVal0))
{
//已发生翻滚,请增加我们的翻滚计数器
滚动计数++;
}
//转期帐户
uiBigVal=newVal+(maxInt*滚动计数);
感谢您的输入。很难理解您在做什么。在代码中添加一些注释来解释每个步骤的意图会有所帮助。但你的问题似乎是你没有处理第二次翻滚,即高阶单词从1切换到2。嗯,你太努力了。只需累积
val-prevVal
。这假设您使用的是2的补码系统,似乎您使用的是\uu int64
。请检查此链接:
-2483649 4292483647 4291483647 4292483647 4291483647
-1483649 4293483647 4292483647 4293483647 4292483647
-483649 4294483647 4293483647 4294483647 4293483647
516351 516351 4294483647 4295483647 4294483647 (rollover detected here and we are still good)
1516351 1516351 516351 1516351 4295483647
2516351 2516351 1516351 2516351 1516351 //oops!!!
3516351 3516351 2516351 3516351 2516351
//the rest of the code is the same as above
if ((newVal < modVal && prevVal > 0))
{
//rollover has occurred, increment our rollover counter
rolloverCount ++;
}
//account for the rollover
uiBigVal =newVal + (maxInt * rolloverCount);