我必须阅读MS-DOS程序使用的一些遗留数据文件。其中大部分都非常简单,但我无法找出一种数据类型; 表示整数的6字节序列。
一些例子:
{{1}}
可能有用的事情:
非常欢迎任何帮助!
快速更新
上面的示例显示了一个字节序列,此处表示为十六进制值,从文件中剪切并粘贴到此处。我确定字节序列是代表一个数字,因为我可以更改MS-DOS程序中的数值,保存到文件,并比较结果。
阅读&写数据
为了从二进制形式读取和写入48位实数,您可以查看:
PHP: Convert double to Pascal 6-byte (48 bits) real format
答案 0 :(得分:6)
这看起来像 6字节[48位]实浮点帕斯卡格式
Pascal real的值介于2.9E-39(2.9 x 10 ^ -39)到1.7E38(1.7 x 10 ^ 38)之间。
如果是这种情况,您可以使用此方法将十六进制数转换为double。
[我从文章末尾列出的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);