【问题标题】:Reading a double stored in a binary format in a character array读取以二进制格式存储在字符数组中的双精度
【发布时间】:2013-02-10 23:58:03
【问题描述】:

我正在尝试读取以特定二进制格式存储在 char 数组中的浮点数。格式如下,每个字母代表一个二进制数字:

SEEEEEEE MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM

website 中更清楚地解释了格式。基本上,指数采用 Excess-64 表示法,尾数归一化为 1/16 的值。为了得到数字的真值,尾数乘以 16 的指数真值的幂。

基本上,到目前为止我所做的是提取符号和指数值,但我在提取尾数时遇到了麻烦。我正在尝试的实现是相当蛮力的,并且在代码方面可能远非理想,但在我看来它是最简单的。基本上是:

unsigned long a = 0;
for(int i = 0; i < 7; i++)
    a += static_cast<unsigned long>(m_bufRecord[index+1+i])<<((6-i)*8);

它获取存储在 char 数组中的每个 8 位字节大小,并根据它在数组中的索引将其左移。所以如果我的数组如下:

{0x3f, 0x28, 0xf5, 0xc2, 0x8f, 0x5c, 0x28, 0xf6}

我期待a 取值:

0x28f5c28f5c28f6

但是,通过上述实现 a 获取值:

0x27f4c18f5c27f6

稍后,我使用以下代码将长整数转换为浮点数:

double m = a;

m = m*(pow(16, e-14));
m = (s==1)?-m:m;

这里出了什么问题?另外,我很想知道如何理想地实现这样的转换?

【问题讨论】:

  • 这就像前两天的第十个问题一样。这是某种家庭作业的截止日期吗?您的教授是否知道您正在就这个问题寻求答案?
  • 好吧,不幸的是,我还没有看到以前的问题,尽管我搜索了以前是否有人问过类似的问题。如果你必须知道的话,这里的上下文是关于读取 GDSII 格式文件(一种主要用于存储 IC 布局的文件格式。)更多信息在这里:(boolean.klaasholwerda.nl/interface/bnf/gdsformat.html)此外,没有任何教授参与。
  • 很公平,并为影射道歉。
  • long 实际上是否有足够的大小容纳 56 位?在任何情况下,您都可以直接编写 IEE754 double 的二进制表示,而无需中间步骤。
  • 格式真的匹配64位吗? double 中的指数不是超过 8 位吗?

标签: c++ floating-point binary


【解决方案1】:

我没有尝试运行你的代码,但我怀疑你得到这个的原因:

0x27f4c18f5c27f6

而不是

0x28f5c28f5c28f6

是因为您在其前面的单元格中有一个“负数”。您的 8 位字节数组是有符号值还是无符号值?如果你不签名,我希望它会更好。 [或者移动你的演员,使其在轮班操作之前]。

【讨论】:

  • 我的字节数组是一个 char*,所以它是有符号的,但我想我是在移位操作之前进行转换。上面的代码没有这样做吗?
  • 我会在“添加”之前打印中间值[我个人会在值中或值中使用|,因为这样可以在添加负值时节省任何不需要的“借用”等]。
  • 这肯定是问题所在,static_cast&lt;unsigned long&gt;(0xf3)(0xf3 实际上是存储在 char* 数组中的值)导致0xfffffffffffffff3 这肯定不是我想要的。将表达式更正为static_cast&lt;unsigned long&gt;(0xf3)&amp;0xff 似乎可以解决问题,但我不明白这是否是预期行为?
  • 我认为发生的情况是它先扩展为 long,然后转换为无符号,这与您需要的相反。我过去也遇到过类似的问题,必须先进行双重转换或使用unsigned [这可能也可以解决您的问题]。
  • 有道理。由于默认 int 的大小,使用 static_cast&lt;unsigned&gt;() 不适用于我的情况。我将不得不使用双重演员或static_cast&lt;unsigned long&gt;()&amp;0xff。我想我会支持双重演员,因为它具有更好的可读性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-08
  • 1970-01-01
相关资源
最近更新 更多