Han*_*etz 7 java integer-overflow
我有一个导致整数溢出的错误,导致错误(负)时间戳被写入数据库.该代码已经是固定的,但我想修正错误的数据,太.
我想,我可以采取错误的结果并添加Integer.MAX_VALUE,但这似乎不起作用,它让我高价值.我offset在下面的代码片段中有值,但不存储输入值.
以下代码重现了该错误:
@Test
public void testArexxConversion()
{
// The input values represent seconds since midnight, Jan 1, 2000 UTC
final int sample = 361450072; // A sample input value drawn from production
// I use the offset from the UNIX epoch to convert the vakue to UNIX seconds
final int offset = 946684800; // midnight, Jan 01 2000 UTC in UNIX seconds
// This was the buggy line in my code, the assertion will fail
long result = (sample + offset) * 1000;
// Prints 'Result is negative: -1830153280'
Assert.assertTrue(result > 0, String.format("Result is negative: %d", result));
// This is for comparison
Date dt = new Date(offset * 1000);
Assert.assertEquals(dt.getTime() + sample * 1000, result);
}
Run Code Online (Sandbox Code Playgroud)
要修复数据库中的错误,您可以对所有错误数据执行以下操作:
long new_result = old_buggy_result + 1309965025280L;
Run Code Online (Sandbox Code Playgroud)
常量数是这样找到的:
result值result值应该是多少?result值进行加法以找到正确的结果。但这只有在您将sample和保存offset在您的数据库或其他地方时才有可能。
否则,它取决于原始计算期间发生的回绕次数:
long size_of_int = (long)Math.pow(2, 32);
int number_of_wraps = 305 // Only correct in your example!
// You can't deduct the number of wraps from
// the wrong value alone, because that information
// is lost in the modulo (the "wrap")
long correct_number = wrong_number + size_of_int * number_of_wraps;
Run Code Online (Sandbox Code Playgroud)
如果您的数据库中的数字足够接近您的样本值,这意味着您可以执行上述操作,使用 305 作为换行数。
这里的操作:
(sample + offset) * 1000;
Run Code Online (Sandbox Code Playgroud)
是使用int和 not计算的long。但结果“太大”而无法保存在int变量中。这就是为什么你有溢出。
将其更改为:
((long) sample + offset) * 1000L;
Run Code Online (Sandbox Code Playgroud)
所以现在+和*操作将使用long值来完成,结果将是一个long不会溢出的值。
| 归档时间: |
|
| 查看次数: |
3116 次 |
| 最近记录: |