问题"算术运算导致溢出"

时间:2015-11-20 07:01:35

标签: c#

我有这个表达

 long balance = (long)answer.Find(DppGlobals.TAG_TI_BALANCE).Get_QWORD();

引起溢出的异常。右侧的值为无符号类型,值为:18446744073708240732。

如何避免此异常,请使用unchecked

PS等效C ++实现返回balance = -1310984,我也需要相同的值。

为什么会有这样的例外?

通过使用未经检查确实现在也在C#端我得到-1310984。有人可以建议,我是否会以某种方式丢失数据?

2 个答案:

答案 0 :(得分:2)

使用uncheck也会削减你的价值,但你没有例外,你会得到错误的号码。我想你会做点什么改变你的代码,不掩盖你的例外。

long balance = (unchecked))(long)answer.Find(DppGlobals.TAG_TI_BALANCE).Get_QWORD());

为什么会有这样的例外?

你得到一个错误是非常好的。因为如果你在一切都是数字的领域工作,你可能会犯错并且不理解这一点。所以RunTime会告诉你你的错误< / p>

答案 1 :(得分:2)

鉴于评论,听起来你只需要使用未经检查的算术 - 但你应该关注在你的API中使用ulong。如果您的目标是传播8个字节的数据,并根据上下文将其解释为无符号整数或有符号整数,那么您就可以了 - 只要没有任何内容以“错误”形式对其进行算术运算。 / p>

重要的是要理解为什么会发生这种情况,并且用较小的数字解释这一点要容易得多。我将以bytesbyte为例。 byte的范围是0到255(包括0和255)。 sbyte的范围是-128到127(含)。两者都可以存储256个不同的值。没问题。

现在,使用未经检查的转化,可以说:

byte a = GetByteFromSomewhere();
sbyte b = (sbyte) a;
StoreSByteSomewhere(b);
...
sbyte b = GetSByteFromStorage();
byte a = (byte) b;

如果你正在做所有,那很好。 byte值为-1将成为sbyte值255,反之亦然 - 基本上它只是以不同方式解释相同的位模式。

但是如果你在处理“错误”类型时对值执行其他操作,那么你可能得到意想不到的答案。例如,考虑“除以3”。如果你将-9除以3,你得到-3,对吗?如果你有:

byte original = -9;
sbyte converted = (sbyte) original;
sbyte divided = converted / 3;
byte result = (byte) divided;

...然后你得到-2而不是-3的结果,因为算术运算的方式。

现在全部用于未经检查的转化。当您进行检查转换时,它不仅会解释这些位 - 而是将该值视为数字。例如:

// In a checked context...
byte a = 128;
sbyte b = (sbyte) a; // Bang! Exception

那是因为128(作为数字)超出sbyte的范围。这就是你的情况 - 数字18446744073708240732超出了long的范围,所以你得到了一个例外。已检查的转换将其视为数字,可以进行范围检查,而不是仅仅将未经检查的转换重新解释为long(这会导致您想要的负数)。