如何Z'FEDCBA09'
将最高有效位等于1 的boz-literal-constant 或任何其他位模式分配给整数?
标准规定:
INT(A[,KIND])
:如果A
为boz-literal-constant,则结果的值是根据16.3中的模型,其位序列与根据16.3.3通过填充或截断修改的A的位序列相同的值。最高有效位为1的位序列的解释取决于处理器。
因此,以下分配可能会失败(假定integer
默认为32位):
program boz
implicit none
integer :: x1 = int(Z'FEDCBA09')
integer :: x2 = int(Z'FFFFFFFF')
integer :: x3
data x3/Z'FFFFFFFF'/
end program
Run Code Online (Sandbox Code Playgroud)
使用gfortran,这仅在添加时起作用,但这会带来-fno-range-check
额外的不良影响:
-fno-range-check
:禁用在编译过程中对常量表达式的简化结果进行范围检查。例如,当简化时,GNU Fortran将在编译时给出错误。a = 1. / 0.
使用此选项,将不会给出错误,并且将为值分配+ Infinity。如果表达式的计算结果超出的相关范围[-HUGE():HUGE()]
,则该表达式将替换为-Inf
或+Inf
适当替换。类似地,DATA i/Z'FFFFFFFF'/
在大多数系统上都会导致整数溢出,但是-fno-range-check
该值将“环绕”并且i
将被初始化为-1
。
我尝试了以下方法,效果很好,但仍然不是100%
integer(kind=INT32) :: x1 = transfer(real(Z'FEDCBA09',kind=REAL32),1_INT32)
integer(kind=INT32) :: x1 = transfer(real(Z'FFFFFFFF',kind=REAL32),1_INT32)
Run Code Online (Sandbox Code Playgroud)
后一种情况对于gfortran失败,因为它抱怨Z'FFFFFFFF'
代表NaN。
使用IOR(0,Z'FEDCBA09')
也会失败,因为它会转换boz-literalINT
问题:如何使用boz-literal-constant可靠地分配位模式?也就是说,与使用的编译器(GNU,SUN,PGI,NAG等)无关。
x = ior(ishft(int(Z'FEDC'),bit_size(x)/2),int(Z'BA09'))
Run Code Online (Sandbox Code Playgroud)
这将适用于任何编译器,并且不需要任何其他数据类型即可成功。
小智 5
对于需要-fno-range-check
在什么将是gfortran 10.1它被释放时已被删除。在10.1中,您所指定的位模式将被视为32位无符号整数,并强制执行doubles-complement环绕语义。
您的第一个代码段中print
添加了一条语句
program boz
implicit none
integer :: x1 = int(Z'FEDCBA09')
integer :: x2 = int(Z'FFFFFFFF')
integer :: x3
data x3/Z'FFFFFFFF'/
print *, x1, x2, x3
end program
Run Code Online (Sandbox Code Playgroud)
产量
$ gfortran -o z file.f90
$ ./z
-19088887 -1 -1
Run Code Online (Sandbox Code Playgroud)
并且不需要该-fno-range-check
选项。提议的transfer
方法也是如此:
program boz
use iso_fortran_env
implicit none
integer(kind=INT32) :: x1 = &
& transfer(real(Z'FEDCBA09',kind=REAL32),1_INT32)
integer(kind=INT32) :: x2 = &
& transfer(real(Z'FFFFFFFF',kind=REAL32),1_INT32)
print '(I0,1X,Z8.8)', x1, x1
print '(I0,1X,Z8.8)', x2, x2
end program
Run Code Online (Sandbox Code Playgroud)
返回:
$ gfortran -o z file.f90
$ ./z
-19088887 FEDCBA09
2143289344 7FC00000
Run Code Online (Sandbox Code Playgroud)
注意: gfortran转换sNaN
为qNan
,这是一个bug,但是没有人在乎。
归档时间: |
|
查看次数: |
125 次 |
最近记录: |