2

我的任务是将一些 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] 数组中的正确方法是什么?

4

2 回答 2

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 规范,你应该能够重现它)

于 2012-08-08T16:00:02.267 回答
0

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

你是,在声明中

CALL MKS1(x,a)

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

您希望 PHP 程序读取的 4 个字符是什么?例如,如果您的 Fortran 将REAL4 个字节写入二进制文件,而您的 PHP 将 4 个字节读取为 4 个单个字符,您会得到您想要的字符吗?我不确定你的要求是什么。

于 2012-08-08T15:32:15.237 回答