从fortran返回四精度变量

问题描述 投票:2回答:1

因此,我试图从fortran返回一个四精度(128位)值,并在python中进行操作。但是我得到的返回值似乎与我的期望不符。

Fortran代码:

module testquad

    implicit none

    integer, parameter :: qp = selected_real_kind(p=30)

    contains

    real(qp) function func_quad()
        real(qp) :: x

        x = 5_qp

        write(*,*) x,sizeof(x)
        write(*,'(B128)') x

        func_quad = x

    end function func_quad

end module testquad

编译:

gfortran -fpic -shared -fdump-tree-all -o libtestquad.so testQuad.f90

Python端,我使用c_ubyte * 16数组保存返回值(因为ctypes不公开128位四边形类型)

import ctypes

lib = ctypes.CDLL('./libtestquad.so')

f = getattr(lib, '__testquad_MOD_func_quad')

f.argtypes = []
f.restype = ctypes.c_ubyte*16

result = f()

bb=[]
for i in bytearray(result)[::-1]:
    bb.append(bin(i)[2:].rjust(8,'0'))

bb=''.join(bb)
print(bb)

运行代码,调用fortran函数的输出是:

5.00000000000000000000000000000000000                         16
 1000000000000010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

所以我们得到了5,我们看到大小为16(所以我得到了一个四进制数)

似乎gfortran跳过了打印符号位的第一个0/1。但是我们可以看到它在位模式中具有3个1,其余为0。

跟随四边形上的wikipedia page,然后得到

sign = 0 (gfortran misses this)
exponent = 100000000000001
significand = 0100....

将其转换为:

a = 2**(int('100000000000001',base=2)-16383) # 4
b = 1 + 0/2**1 + 1/2**2 + 0/2**3 .... # 1.25
print(a * b)
5

因此gfortran可以如预期的那样打印数字5的正确位模式。

但是,在结果中用python打印出位模式:

00000000000000000111111110110001001111101010010111111001001010000000000000000000000000000000000000000000000000000000000000000000

明显不同。

我是否已拧紧打印位图案?

gfortran如何返回__float128是否有特殊之处,这意味着我不能仅仅将其解释为16个字节?

ctypes如何处理返回破坏事物的c_bytes数组是否有特殊之处?

还有什么?

额外:

使用-fdump-tree-all并查看我们看到的.original文件:

func_quad ()
{
  real(kind=16) x;
  real(kind=16) __result_func_quad;

  x = 5.0e+0;
  // snip write statement code
  __result_func_quad = x;
  return __result_func_quad;
}

因此似乎没有发生任何“特殊”情况,没有将变量分配给结构/指针/数组以处理四元类型。

python fortran ctypes gfortran
1个回答
0
投票

好像我遇到了这个https://stackoverflow.com/a/423479/2270574答案。指出不能将字节数组用于浮点数,因为它没有存储在常规%eax寄存器中。

© www.soinside.com 2019 - 2024. All rights reserved.