gpt4 book ai didi

fortran - 如何将位模式 Z'FEDCBA09' 分配给 32 位整数

转载 作者:行者123 更新时间:2023-12-04 06:38:57 28 4
gpt4 key购买 nike

如何将 boz-literal-constant Z'FEDCBA09' 或最高有效位等于 1 的任何其他位模式分配给整数?

标准规定:

INT(A[,KIND]): If A 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 simplifying a = 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" and i will be initialized to -1 instead.

source: GNU Compiler Collection, gfortran manual

我尝试了以下方法,效果很好但仍然不是 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

问题如何使用 boz-literal-constant 稳健地分配位模式?也就是说,与使用的编译器(GNU、SUN、PGI、NAG 等)无关。

答案:目前最可靠的答案是Jim Rodesthis 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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com