double转换成帕斯卡尔6字节(48位)real格式 [英] Convert double to Pascal 6-byte (48 bits) real format

查看:363
本文介绍了double转换成帕斯卡尔6字节(48位)real格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要做的包含在原有文件中的数据做一些工作。为此,我需要阅读的的Turbo Pascal的的6个字节(48位)浮点数,从PHP。在Turbo Pascal的数据类型通常被称为real48(规格)。

I need to do some work on data contained in legacy files. For this purpose, I need to read and write Turbo Pascal's 6-byte (48 bit) floating point numbers, from PHP. The Turbo Pascal data type is commonly known as real48 (specs).

我有以下的php code为阅读的格式为:

I have the following php code to read the format:

/**
 * Convert Turbo Pascal 48-bit (6 byte) real to a PHP float
 * @param binary 48-bit real (in binary) to convert
 * @return float number
 */
function real48ToDouble($real48) {
    $byteArray = array_values( unpack('C*', $real48) );
    if ($byteArray[0] == 0) {
        return 0; // Zero exponent = 0
    }

    $exponent = $byteArray[0] - 129;    
    $mantissa = 0;

    for ($b = 1; $b <= 4; $b++) {
        $mantissa += $byteArray[$b];
        $mantissa /= 256;
    }
    $mantissa += ($byteArray[5] & 127);
    $mantissa /= 128;
    $mantissa += 1;

    if ($byteArray[5] & 128) { // Sign bit check
        $mantissa = -$mantissa;
    }
    return $mantissa * pow(2, $exponent);
}

改编自

现在我需要做相反的:的数据类型

Now I need to do the reverse: write the data type.

结果
注意:
我知道的回答的问题转换C#双德尔福Real48的,但它似乎非常哈克,我会想更简洁的解决方案是可能的。我的机器本身不支持64位。


Note: I'm aware of the answer to the question Convert C# double to Delphi Real48, but it seems awfully hacky and I would think a much cleaner solution is possible. AND my machine does not natively support 64-bits.

推荐答案

在第二次看,在答案公布转换的方法C#双德尔福Real48 的很好的清理pretty。

On a second look, the method posted in the answer to Convert C# double to Delphi Real48 cleaned up pretty nicely.

有关将来参考:

/**
 * Convert a PHP number [Int|Float] to a Turbo Pascal 48-bit (6 byte) real byte representation
 * @param float number to convert
 * @return binary 48-bit real
 */
function doubleToReal48($double) {
    $byteArray = array_values( unpack('C*', pack('d', $double)) ); // 64 bit double as array of integers
    $real48 = array(0, 0, 0, 0, 0, 0);

    // Copy the negative flag
    $real48[5] |= ($byteArray[7] & 128);

    // Get the exponent
    $n = ($byteArray[7] & 127) << 4;
    $n |= ($byteArray[6] & 240) >> 4;

    if ($n == 0) { // Zero exponent = 0
        return pack('c6', $real48[0], $real48[1], $real48[2], $real48[3], $real48[4], $real48[5]);
    }

    $real48[0] = $n - 1023 + 129;

    // Copy the Mantissa
    $real48[5] |= (($byteArray[6] & 15) << 3); // Get the last 4 bits
    $real48[5] |= (($byteArray[5] & 224) >> 5); // Get the first 3 bits
    for ($b = 4; $b >= 1; $b--) {
        $real48[$b] = (($byteArray[$b+1] & 31) << 3); // Get the last 5 bits
        $real48[$b] |= (($byteArray[$b] & 224) >> 5); // Get the first 3 bits
    }

    return pack('c6', $real48[0], $real48[1], $real48[2], $real48[3], $real48[4], $real48[5]);
}

这篇关于double转换成帕斯卡尔6字节(48位)real格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆