初始化值为 -2**31 的整数

Initialize integer with value -2**31

提问人:William Pursell 提问时间:9/8/2012 更新时间:9/8/2012 访问量:518

问:

integer, parameter :: m = -2147483648

导致编译器错误:“整数对于同类来说太大”,但

integer, parameter :: m = -2147483647 - 1

似乎有效并产生正确的结果。我认为这是因为编译器在否定它之前检查2147483648并溢出整数类型。虽然减法 1 hack 似乎可以进行所需的初始化,但是否有“最佳实践”方法可以使用?

福特兰

评论


答:

0赞 Jorge Fuentes González 9/8/2012 #1

2147483648不存在,则最大值为 32 位2147483647。您需要使用整数*8 变量,它是一个 64 位整数,可让您使用更大的数字。

评论

1赞 William Pursell 9/8/2012
虽然 +2147483648 不能用 32 位二进制补码表示,但 -2147483648 可以表示。
0赞 Jorge Fuentes González 9/8/2012
哦,这是真的,你是对的。那么也许问题出在你说什么,在否定之前检查。
1赞 willglynn 9/8/2012 #2

正如您怀疑的那样,编译器将 -2147483648 解释为值 +2147483648 的一元否定,并且该中间值对于有符号的 32 位整数来说太大了。

至于最佳实践,我所看到的每个定义都用以下方式表示:INT_MIN-INT_MAX - 1

我的结论是,最好的做法是依靠编译器的不断折叠来做正确的事情,而不是直接表达这个常量。

评论

0赞 William Pursell 9/8/2012
我是 fortran 的新手:那么最佳实践是使用 ,还是其他什么?-HUGE( m ) - 1
0赞 Chris 9/10/2012
是的,似乎是你最好的选择。-huge(m) - 1
5赞 janneb 9/8/2012 #3

问题在于 Fortran 标准根据“型号”来定义整数,这些整数具有对称的间隔。GFortran(您似乎正在根据错误消息使用它)不允许不是 Fortran 型号的整数文本,即使 2 的补码硬件可以表示此类数字。此检查是在解析阶段完成的,因此,当诸如“-huge(0) - 1”之类的表达式在编译过程中被恒定折叠时,不会出现错误消息。

使用 GFortran,您可以使用 -fno-range-check 禁用此检查。