首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将双字节转换为Pascal 6字节(48位)真实格式

将双字节转换为Pascal 6字节(48位)真实格式
EN

Stack Overflow用户
提问于 2015-08-11 11:18:32
回答 1查看 2K关注 0票数 4

我需要对遗留文件中包含的数据做一些工作。为此,我需要从PHP中读取和编写Turbo的6字节(48位)浮点数。Turbo数据类型通常称为real48 (规格)。

我有下面的php代码来读取格式:

代码语言:javascript
复制
/**
 * 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);
}

(改编自)

现在,我需要做相反的操作:编写数据类型。

注意:我知道回答的问题--将C# double转换为DelphiReal48,但这似乎非常麻烦,而且我认为一个更干净的解决方案是可能的。我的机器本机不支持64位。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-12 09:43:57

再看一看,在答案中发布的将C# double转换为Delphi Real48的方法清理得相当不错。

供日后参考:

代码语言:javascript
复制
/**
 * 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]);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31940355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档