【问题标题】:BitConverter.ToSingle truncates float valuesBitConverter.ToSingle 截断浮点值
【发布时间】:2020-10-26 07:21:21
【问题描述】:

使用 ruby​​ 的 String#unpack 方法将二进制数据转换为浮点值时,我得到以下结果:

[0x7d, 0xe8, 0x80, 0xc5].map(&:chr).join.unpack('e')[0]
# => -4125.06103515625

这被认为是正确的结果。

使用 C# BitConverter.ToSingle 方法我得到以下结果:

var firstVal = BitConverter.ToSingle(new byte[] {0x7d, 0xe8, 0x80, 0xc5}, 0);
// firstVal: -4125.061

因此,该值似乎以某种方式被截断。 有没有办法从二进制表示中提取正确的值(如ruby 示例)?

【问题讨论】:

  • 你是如何打印值的?
  • Console.WriteLine(((double)firstVal).ToString("R")); 打印与 ruby​​ 相同的值。

标签: c# floating-point


【解决方案1】:

我记得,Ruby 只有一种浮点类型,那就是双精度浮点。所以你的 ruby​​ 表达式的值的类型是双精度浮点数,在 C# 中的模拟是“双精度”。所以如果你想得到完全相同的数字,你可以这样做(但我不确定它是否真的很有意义,请参阅@xanatos 评论):

var firstVal = (double) BitConverter.ToSingle(new byte[] {0x7d, 0xe8, 0x80, 0xc5}, 0); 
// firstVal is -4125.06103515625

【讨论】:

  • 人们不得不想知道为什么documentation 声明'e' 格式字符串将返回一个单精度浮点数...文档问题一次又一次...
  • @InBetween 我认为它声明返回值是 Float (唯一的 ruby​​ 浮点类型),但格式“e”意味着字节数组应被视为包含单精度浮点数(因此有 4 个字节和不是 8 像双倍)
  • 哦,哈哈。我将“格式字符串”关联到输出,而不是输入。我猜是有道理的......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
  • 2019-09-12
  • 2010-10-13
相关资源
最近更新 更多