将Fortran REAL打包例程转换为PHP

时间:2012-08-08 14:44:39

标签: php fortran pack

我的任务是将一些Fortran代码转换为PHP,并且遇到了最后一道障碍。

本质上,Fortran将REAL转换为二进制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的等价物打包成char [4]数组的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

结果很简单。

您的FORTAN REAL存储为IEEE 754 32位浮点数。

od的输出具有误导性。将其转换为十六进制给出以下内容。

0115040 0134631 0005077

0x20, 0x9A, 0x99, 0xB9, 0x3f, 0x0a

文件的第一个和最后一个字节是冗余的,它们分别是空格和回车符。我们所追求的是中间的4个字节。

使用pack我们可以转换浮点数(警告 - 字节顺序 依赖于机器)。

以下内容:

var_dump(bin2hex(pack('f', 1.450)));

给我们一个熟悉的字节序列。

string(8) "9a99b93f"

因此,不是转换为十六进制,而是将其输出到开头有空格并且末尾有回车符的文件,并且您将拥有相同的文件。 (只要您的PHP /机器配置不会对浮点数做些什么 - 但即使这样,如果您遵循IEEE 754规范,您也应该能够重现它)

答案 1 :(得分:0)

这可能是一个扩展的评论而不是答案。

你在声明中

CALL MKS1(x,a)

传递一个REAL参数,其中子例程需要一个4个长度为1个字符的数组。你应该得到发生在你身上的所有不好的事情:-)你只能编译它,因为你没有在你的子程序上需要显式接口。

您希望PHP程序读取的4个字符是什么?例如,如果您的Fortran将REAL写入二进制文件中的4个字节,并且您的PHP读取4个字节作为4个单个字符,那么您是否会获得所需的字符?我不确定你的要求是什么。