【问题标题】:Translating an 8 byte value in to an actual number: [closed]将 8 字节值转换为实际数字:[关闭]
【发布时间】:2013-12-08 11:41:24
【问题描述】:

我有 8 个字节代表一个数字。我给出的描述是:

"有符号 Little-Endian 编码的八字节整数字段,带有八 隐含小数位"

当从文件转储中“挖掘”数据时,八个字节是(我已经包含了字符表示,只是为了使二进制文件清晰):

  • [0] = 0 ('\0')
  • [1] = 86 ('v')
  • [2] = 41 (')')
  • [3] = 50 ('2')
  • [4] = 48 ('0')
  • [5] = 0 ('\0')
  • [6] = 0 ('\0')
  • [7] = 0 ('\0')

在查找了字节序维基百科文章后,我认为我需要从 [7] 开始并向后工作到 [0](文件顺序是从 [0] 到 [7])。但我不确定我需要对这些值做什么。

谁能帮我算出这个数字是多少(这样我就可以将这 8 个字节分配给一个双精度字节)?

【问题讨论】:

  • 也许如果你有一些示例代码(不工作很好)显示你正在尝试做什么,以及正确答案应该是什么以及你的答案是什么代码正在生成,您的要求会更清楚。
  • @mah 如果我能提供,我就不会问这个问题了。最后一句话说明了我正在尝试做的事情。给定这些字节-我想创建一个双重表示。
  • 啊,我就知道肯定跟财政有关。但是小数点后8位?好的,也许是为了在货币之间进行转换......
  • 如果你输入*(long long*)bytes 并乘以 1E-8,这是一个不错的整数,2070.0。清楚地询问生成数据的人是明智的做法。
  • @HansPassant 你能告诉我你在那里做了什么吗?!字节是 char[8] 吗?!你有正确的值

标签: c binary double computer-science endianness


【解决方案1】:

你的假设是错误的 LE 意味着第一个字节是具有最低意义的字节。

要便携地转换它,你可以使用

uintmax_t read_le_value(char * data, size_t len)
{
    uintmax_t value = 0;
    size_t i;
    for (i=0; i<len; i++) {
        value |= data[i] << (8*i);
    }
    return value;
}

你可以用

调用这个函数
int64_t result = read_le_value(array, sizeof array);

请注意,这会调用实现定义的行为:在不使用二进制补码存储有符号值的架构上,它可能会中断。

如果没有其他点,这个 64 位值就可以了:

隐含八位小数

可能是指它可能是一个定点表示法并且1200000000 的值确实意味着12.00000000

因此,您应该将结果除以 1E8 (=100000000) 以获得想要的结果。

但请注意,转换为 double 会丢失精度,因为 double 只有 53 位精度。

因此,表示为 100000000000000001 的值 1000000000.00000001 将转换为 1000000000.0:如果减去此数字,您将得到 0.0,而不是您想要的 .00000001。

【讨论】:

  • 啊,好吧,所以我们所做的就是将每个字节作为二进制写入,将 8 个字节中的位粘贴在一起,然后将所有单独的位转换为 64 位表示?由于整个“隐含小数位”部分,我很担心。
  • @user997112 我添加了一段关于此的内容。
  • 你认为“Signed Little-Endian”中的“signed”是否意味着data[7]或某个地方存在符号位?哦,我在 int64_t result = read_le_value() 中的 unintmax_tint64_t 转换中看到了这一点
  • @chux 是的,但是在将 uintmax_t 分配给 int64_t 时会自动转换。
  • @user997112 他们来自C99的&lt;stdint.h&gt;
猜你喜欢
  • 2014-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 2015-07-03
  • 1970-01-01
相关资源
最近更新 更多