我正在使用一个 API,它在 long 类型的变量中提供一些数据。这个变量的值在增加,会多次翻转,遗憾的是没有办法修改API。我正在尝试使用类似于我在下面包含的测试工具的代码来检测和补偿溢出,最终我会将数据转换为 unsigned long long,然后转换为 double:
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;
所以这行得通,但我的长期价值是多次滚动,我没有正确处理。为了测试这段代码,我用以下方式调用它
first =2147483647;
for (int i = 0; i < 100000; i ++)
{
DetectRolloverOneNumber(first);
first += 1000000;
这是我的输出
val (long) newVal (ulong) modVal uiBigVal prevVal
2147483647 2147483647 0 2147483647 0
-2146483649 2148483647 2147483647 2148483647 2147483647
-2145483649 2149483647 2148483647 2149483647 2148483647
-2144483649 2150483647 2149483647 2150483647 2149483647
-2143483649 2151483647 2150483647 2151483647 2150483647
-2142483649 2152483647 2151483647 2152483647 2151483647
到目前为止一切顺利,即使我们通过了有符号 32 位长的最大值,值也按预期增加了 100000。
..进一步向下...
-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
所以我弄错了。有人对如何正确处理翻转有任何提示吗?任何意见,将不胜感激。谢谢!