在 Fortran 中访问无符号整数值

rob*_*nce 5 unsigned fortran integer fortran95 fortran2003

如果我c_int8_t在 Fortran 中有一个变量,并且想要将底层位解释为无符号整数(用于索引而不是任何算术),最有效的转换方法是什么?我想做类似的事情

X( some_function( my_c_int8_t_var ) ) = 1
Run Code Online (Sandbox Code Playgroud)

其中 X 是一个数组,some_function应返回包含无符号值的 c_int16_t my_c_int8_t_var。我已经看到了包括传输、iadd 在内的选项(或者我猜只是一个带有强制转换和添加的简单条件),但我想知道什么是最有效的方法(此索引发生在内部循环中)。当然,它不一定是一个函数 - 如果它可以使用内联表达式来完成,那就太好了。

编辑:如果该方法也适用于其他整数大小,那就太好了......即获取 c_int32_t 中无符号 c_int16_t 的内容并将无符号 c_int32_t 放入 c_int64_t 中。

Vla*_*r F 4

您可以使用transfer()和ichar()函数。就像是

X(ichar(transfer(my_c_int8_t_var,"a")))) = 1
Run Code Online (Sandbox Code Playgroud)

例如

 use iso_c_binding
 write (*,*) ichar(transfer(-1_c_int8_t,"a"))

 end
Run Code Online (Sandbox Code Playgroud)

返回 255。

当你找不到对应的字符类型(例如,16位)时,我会编写一个函数,将巨大的(1._my_integer_kind)添加到该值中。

integer function indx(i)
  integer(c_int16_t),intent(in) :: i

  if (i<0) then
    indx = 2*(huge(i)+1) + i
  else
    indx = i
  end if
end function indx
Run Code Online (Sandbox Code Playgroud)

或者

  integer function indx2(i)
    integer(c_int8_t),intent(in) :: i

    indx2 = TRANSFER([i,0_c_int8_t],1_c_int16_t)
  end function indx2
Run Code Online (Sandbox Code Playgroud)

最后一种情况仅适用于小端平台。

您可以为该函数创建一个通用接口。

 write (*,*) indx(-2_c_int16_t)
Run Code Online (Sandbox Code Playgroud)

给出 65534