- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何将 boz-literal-constant Z'FEDCBA09'
或最高有效位等于 1 的任何其他位模式分配给整数?
标准规定:
INT(A[,KIND])
: IfA
is a boz-literal-constant, the value of the result is the value whose bit sequence according to the model in 16.3 is the same as that of A as modified by padding or truncation according to 16.3.3. The interpretation of a bit sequence whose most significant bit is 1 is processor dependent.source: Fortran 2018 Standard
因此以下赋值可能失败(假设integer
默认为32位):
program boz
implicit none
integer :: x1 = int(Z'FEDCBA09')
integer :: x2 = int(Z'FFFFFFFF')
integer :: x3
data x3/Z'FFFFFFFF'/
end program
使用 gfortran,这仅在添加 -fno-range-check
时有效,但这会引入额外的不良影响:
-fno-range-check
: Disable range checking on results of simplification of constant expressions during compilation. For example, GNU Fortran will give an error at compile time when simplifyinga = 1. / 0.
With this option, no error will be given and a will be assigned the value +Infinity. If an expression evaluates to a value outside of the relevant range of[-HUGE():HUGE()]
, then the expression will be replaced by-Inf
or+Inf
as appropriate. Similarly,DATA i/Z'FFFFFFFF'/
will result in an integer overflow on most systems, but with-fno-range-check
the value will "wrap around" andi
will be initialized to-1
instead.
我尝试了以下方法,效果很好但仍然不是 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)
后一种情况在 gfortran 中失败,因为它提示 Z'FFFFFFFF'
代表 NaN。
使用 IOR(0,Z'FEDCBA09')
也失败,因为它使用 INT
问题如何使用 boz-literal-constant 稳健地分配位模式?也就是说,与使用的编译器(GNU、SUN、PGI、NAG 等)无关。
答案:目前最可靠的答案是Jim Rodes在 this comment :
x = ior(ishft(int(Z'FEDC'),bit_size(x)/2),int(Z'BA09'))
这适用于任何编译器,不需要任何其他数据类型即可成功。
最佳答案
对于 -fno-range-check
的需求在 gfortran 10.1 发布时已被删除。在 10.1 中,您指定的位模式将被视为 32 位无符号整数,并且强制执行二进制补码环绕语义。
添加了 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
产量
$ gfortran -o z file.f90
$ ./z
-19088887 -1 -1
并且不需要 -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
返回:
$ gfortran -o z file.f90
$ ./z
-19088887 FEDCBA09
2143289344 7FC00000
注意:gfortran 将sNaN
转换为qNan
,这是一个错误,但没人关心。
关于fortran - 如何将位模式 Z'FEDCBA09' 分配给 32 位整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58308414/
我是一名优秀的程序员,十分优秀!