Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何知道值溢出而不重复运行时溢出异常_C#_Integer Overflow - Fatal编程技术网

C# 如何知道值溢出而不重复运行时溢出异常

C# 如何知道值溢出而不重复运行时溢出异常,c#,integer-overflow,C#,Integer Overflow,因此,问题是: 给定一个表示给定编译器(语言?)中最大可能数的本机整数类型,例如C#中的ulong,如何检测表示数字的输入字符串将溢出该给定类型可表示的最大值,而不会返回到选中的上下文和运行时OveflowException 显然,C#编译器可以检测常量整数溢出: ulong l = 18446744073709551615; //ok ulong l = 18446744073709551616; //compile time error: Integral constant is too l

因此,问题是:

给定一个表示给定编译器(语言?)中最大可能数的本机整数类型,例如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.

这样的事情算是解决方案吗

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
决定它溢出的方式相当简单,但您确实需要知道如何解析整数
ulong.Parse
一次解析输入的一个字符。它维护
ulong
结果,对于每个字符,它将结果乘以10,然后将字符的值(0到9)相加,并一直这样做,直到输入用完或结果溢出为止

有两种溢出检查,因为有两种东西可以溢出:10的乘法和加法。为了检查乘法运算不会溢出,将当前结果与
1844674407370955161
进行比较。如果结果大于该值,且仍有数字剩余,则算法退出,并报告溢出。请注意,此数字与ulong.MaxValue相同,最后一位数字已删除,使其成为可以乘以10而不会溢出的最大整数

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


就这样,真的。如果字符用完而未触发上述两项检查中的任何一项,则会成功解析该数字,否则将导致溢出。

TryParse
这样的幕后异常是否也算作不允许?您可以看看,路上没有
try catch
。但是,我不知道编译器实际使用的方式。@interween:“如果我没有弄错,TryParse只包装确实引发运行时异常的解析”。不,这是一个无异常的实现。这就是重点。您可以使用未选中的
上下文并进行类似硬件的溢出检测,但不确定这是否比异常好。@中间:出于某种原因,我上面指向
Uint64.TryParse
的链接不正确,以下是我最初想要链接的内容:很好的一个:)我们曾想过这样做,但这似乎是一种黑客行为。我们想要一些聪明的数学技巧,但似乎并没有。@在两者之间,更合适的方法是实现自己的解析器。看见