编译器错误-9223372036854775808L(&Q;溢出&Q)

人气:172 发布:2023-01-03 标签: .net vb.net long-integer

问题描述

Long data type的范围是-92233720368547758089223372036854775807,但以下语句生成编译器错误"BC30036:Overflow":

Dim a As Long = -9223372036854775808L

Try it online!

为什么这是一个错误?如何在代码中指定常量-9223372036854775808

推荐答案

为什么这是一个错误?

编译器将表达式-9223372036854775808L解析为应用于十进制整数文字9223372036854775808L的一元减号运算符。根据VB.NET specification:

十进制整数文字是由十进制数字(0-9)组成的字符串。

和:

如果整型文字的类型大小不足以容纳整型文字,则会导致编译时错误。

9223372036854775808L对于Long太大,因此会出现溢出错误。 (减号不是整型文字的一部分。)

如何在代码中指定常量-9223372036854775808?

要按字面意思指定-9223372036854775808,请使用十六进制文字:

Dim a As Long = &H8000000000000000

VB.NET规范也暗示了这一点:

十进制文字直接表示整型文字的十进制值,而八进制和十六进制文字表示整型文字的二进制值(因此,&;H8000S为-32768,不是溢出错误)。

当然,为了清楚起见,您可能应该使用Long.MinValue而不是文字:

Dim a As Long = Long.MinValue

C#怎么办?

正如勒内·沃格特指出的,等价的语句在C#中编译得很好:

long a = -9223372036854775808L;

这是因为(不像VB.NET)C# supports this as a special case:

如果DECIMAL_INTEGER_INTEGER_TEXAL的值为9223372036854775808(2^63),并且INTEGER_TYPE_SUFFIX或INTEGER_TYPE_SUFFIXLl作为紧跟在一元减号运算符内标识后面的标记出现,则结果是long类型的常量,其值为-9223372036854775808(-2^63)。在所有其他情况下,此类DECIMAL_INTEGER_TEXAL的类型为ulong

19