long 型の変数でデータを提供する API を使用しています。この変数の値は増加しており、何度もロールオーバーします。残念ながら、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
だから私はこれを間違えています。ロールオーバーを適切に処理する方法に関するヒントはありますか? アドバイスをいただければ幸いです。ありがとう!