我的任务是将一些Fortran代码转换为PHP,但我在最后一个障碍上遇到了困难。
实质上,Fortran将实数转换为二进制的CHAR(4),最终将其写入文件。
Fortran (也让我感到困惑)如下所示:
FUNCTION MKS(x)
CHARACTER (LEN=4) :: MKS ! The 4-character string which is returned to
REAL :: x ! The incoming single-precision variable
CHARACTER (LEN=1), DIMENSION(4) :: a ! A working variable
CHARACTER (LEN=4) :: d ! A working variable
CALL MKS1(x,a) ! Send x - get back a(1), a(2), a(3), a(4)
! Note: x will hold the first 32 bits referenced
! and a will hold the next 32 bits
d = a(1) // a(2) // a(3) // a(4) ! concatenate into 1 string (d)
MKS = d ! assign string to variable MKS
END FUNCTION MKS
SUBROUTINE MKS1 (b,c)
IMPLICIT NONE
CHARACTER (LEN=1), DIMENSION(4) :: b ! array with incoming 32 bits
CHARACTER (LEN=1), DIMENSION(4) :: c ! array with each character returned
INTEGER :: i ! DO Loop counter
DO i=1,4
c(i) = b(i)
END DO
END SUBROUTINE MKS1我尝试使用php重新创建这个函数,如下所示
pack('CCCC', $value & 0x000F,
($value>>8) & 0x000F,
($value>>16) & 0x000F,
($value>>24) &0x000F);但是,在使用*nix od命令比较输出值时,会显示完全不同的结果。
在PHP中,什么是将Fortran REAL的等价物打包成char4数组的正确方法?
发布于 2012-08-09 00:00:02
事实证明,这非常简单。
你的实数被存储为一个IEEE 754 32位浮点数。
od的输出具有误导性。将其转换为十六进制将得到以下结果。
0115040 0134631 0005077
0x20, 0x9A, 0x99, 0xB9, 0x3f, 0x0a文件的第一个字节和最后一个字节是多余的,它们分别是一个空格和一个回车。我们要找的位是中间的4个字节。
使用pack我们可以从浮点数转换(警告- endianness依赖于机器)。
以下内容:
var_dump(bin2hex(pack('f', 1.450)));给了我们一个熟悉的字节序列。
string(8) "9a99b93f"因此,不是转换为十六进制,而是将其输出到一个文件中,该文件的开头有一个空格,结尾有一个回车,这样你就会得到一个完全相同的文件。(只要你的PHP/机器配置没有对浮点数做一些疯狂的事情--但即便如此,如果你遵循IEEE754规范,你也应该能够重现它)
发布于 2012-08-08 23:32:15
这可能是一个扩展的评论,而不是一个答案。
在语句中,您是
CALL MKS1(x,a)传递一个实数参数,其中该子例程需要一个长度为4个字符的数组。你应该得到发生在你身上的所有不好的事情:-)你只能编译这个,因为你的子例程没有明确的接口。
您希望PHP程序读取的4个字符是什么?例如,如果您的Fortran在一个二进制文件中将REAL写成4个字节,而您的PHP将4个字节作为4个单字符读取,那么您会得到想要的字符吗?我不确定你的要求是什么。
https://stackoverflow.com/questions/11867055
复制相似问题