如何知道一个值溢出而不重复出现在运行时OverflowException中

本文关键字:OverflowException 运行时 何知道 溢出 一个 | 更新日期: 2023-09-27 18:23:48

所以问题是:

给定一个表示给定编译器(语言?)中可能的最大数字的本机积分类型,例如C#中的ulong,如何检测表示数字的输入字符串将溢出该给定类型可表示的最大值,而不返回到检查的上下文和运行时OveflowException

显然,C#编译器可以检测常量积分溢出:

ulong l = 18446744073709551615; //ok
ulong l = 18446744073709551616; //compile time error: Integral constant is too large.

编译器是否在后台使用运行时OverflowException(或等效程序)?如果是这样的话,有没有一种方法可以真正做到这一点,而不会重复出现运行时异常,或者构建一个可以容纳较大数字的数字类型,如System.Numeric.BigInt?值得注意的是,BigInt在C#中没有本机支持,因为以下是编译时错误,尽管积分常数在类型的范围内:

BigInt i = 18446744073709551616; //compile time error: Integral constant is too large.

如何知道一个值溢出而不重复出现在运行时OverflowException中

像这样的东西算是一个解决方案吗?

string s1 = "18446744073709551616";
string s2 = ulong.MaxValue.ToString();
// assuming s1 contains digits only and no leading zeros
if(
    s1.Length > s2.Length ||
    s1.Length == s2.Length && string.CompareOrdinal(s1, s2) > 0
)
    Console.WriteLine("overflow");

编译器很可能一次只解析输入的一位数字,其代码与ulong.Parse类似,但显然适用于任务。

ulong.Parse决定其溢出的方式相当简单,但您确实需要知道整数是如何解析的。CCD_ 8一次解析输入的一个字符。它保持ulong的结果,对于每个字符,它将结果乘以10,然后将字符的值相加(从0到9),并一直这样做,直到输入用完或结果溢出。

有两种溢出检查,因为有两种东西可以溢出:乘10和加法。为了检查乘法运算是否溢出,将当前结果与1844674407370955161进行比较。如果结果大于该值,并且还剩下数字,则算法退出,报告溢出。观察这个数字与去掉最后一位的ulong.MaxValue相同,使其成为可以乘以10而不溢出的最大整数。

接下来,它需要检查从0到9的数字相加是否会溢出。它首先将数字相加,然后检查结果是否减少而不是增加。这是因为加法是如何在CPU内部实现的;基本上,结果的顶部被丢弃,因为它不适合。

就这样,真的。如果字符用完而没有触发上面两个检查中的任何一个,则数字解析成功,否则就是溢出。

相关文章:
  • 没有找到相关文章