这个6字节(48位)数字的浮点数是什么类型的?整数?

时间:2015-08-10 20:22:40

标签: binary hex

我必须阅读MS-DOS程序使用的一些遗留数据文件。其中大部分都非常简单,但我无法找出一种数据类型; 表示整数的6字节序列。

一些例子:

{{1}}

有人知道这是什么类型的格式吗?

可能有用的事情:

  • 文件格式来自MS-DOS时代(准确地说是1994年);
  • 文件格式在其他任何地方都不使用特殊类型;
  • 将第一个字节的值增加1通常会使数值加倍;
  • (其他)字节和整数通常是签名的。

非常欢迎任何帮助!

快速更新

上面的示例显示了一个字节序列,此处表示为十六进制值,从文件中剪切并粘贴到此处。我确定字节序列是代表一个数字,因为我可以更改MS-DOS程序中的数值,保存到文件,并比较结果。


阅读&写数据

为了从二进制形式读取和写入48位实数,您可以查看:
PHP: Convert double to Pascal 6-byte (48 bits) real format

2 个答案:

答案 0 :(得分:6)

这看起来像 6字节[48位]实浮点帕斯卡格式

Pascal real的值介于2.9E-39(2.9 x 10 ^ -39)到1.7E38(1.7 x 10 ^ 38)之间。

如果是这种情况,您可以使用此方法将十六进制数转换为double。

C#代码

[我从文章末尾列出的wiki中拿走了它,但无论如何: Turbo Pascal Real]

// This program expects a byte array named real48[6] to be loaded with the 6 bytes of the real from the file. 

Double exponentbase = 129d;
Double exponent = real48[0] - exponentbase; // The exponent is offset so deduct the base.

// Now Calculate the mantissa
Double mantissa = 0.0;
Double value = 1.0;
// For Each Byte.
for (int i = 5; i >= 1; i--)
{
    int startbit = 7;
    if (i == 5)
    { startbit = 6; } //skip the sign bit.

    //For Each Bit
    for (int j = startbit; j >= 0; j--)
    {
        value = value / 2;// Each bit is worth half the next bit but we're going backwards.
        if (((real48[i] >> j) & 1) == 1) //if this bit is set.
        {
            mantissa += value; // add the value.
        }

    }
}

if (mantissa == 1.0 && real48[0] == 0) // Test for null value
    return 0.0;

if ((real48[5] & 0x80) == 1) // Sign bit check
    mantissa = -mantissa;

return (1 + mantissa) * Math.Pow(2.0, exponent);

如果你想要更现代的| POO代码实现你可以使用代码Simeon Pilgrim在本文中向我们展示:

<强> Pascal 6-byte real to IEEE 8-byte double

  

警告要使用Pilgrim公开的方法,您需要注意字节排序

     
// expl: 100=>                       87 00  00 00   00 48
var theMethodParam = new ushort[] { 0x0087, 0x0000, 0x4800 };

您可以在此处获得有关此主题的更多信息:

<强> Turbo Pascal Real

答案 1 :(得分:0)

此处是REAL48格式的说明:

http://docwiki.appmethod.com/appmethod/1.13/topics/en/Internal_Data_Formats#The_Real48_type

JuanK的C#代码有多个错误:

Real48[0] == 0 

始终等于值0.0

条件

if ((real48[5] & 0x80) == 1)

永远不会是真的。可以改写为

if ((real48[5] & 0x80) == 0x80)

或更简单地

if ((real48[5] & 0x80) != 0)

必须在尾数加1之后应用符号,即

mantissa = 1 + mantissa ;

if ( (real48[5] & 0x80) != 0 ) // Sign bit check
  mantissa = -mantissa;

这是我的修改版本

// This program expects a byte array named real48[6] to be loaded with the 6 bytes of the real from the file.

// real48[0] == 0 is represents the value 0.
if ( real48[0] == 0 )
  return 0.0 ;

Double exponentbase = 129d;
Double exponent = real48[0] - exponentbase; // The exponent is offset so deduct the base.

// Now Calculate the mantissa
Double mantissa = 0.0;
Double value = 1.0;
// For Each Byte.
for (int i = 5; i >= 1; i--)
{
  int startbit = 7;
  if (i == 5)
  { startbit = 6; } //skip the sign bit.

  //For Each Bit
  for (int j = startbit; j >= 0; j--)
  {
    value = value / 2;// Each bit is worth half the next bit but we're going backwards.
    if (((real48[i] >> j) & 1) == 1) //if this bit is set.
    {
      mantissa += value; // add the value.
    }
  }
}

// The significand ia 1 + mantissa.
// This must come before applying the sign.
mantissa = 1 + mantissa ;

if ( (real48[5] & 0x80) != 0 ) // Sign bit check
  mantissa = -mantissa;

return (mantissa) * Math.Pow(2.0, exponent);