2013-10-07 51 views
2

我试图将字节流复制到双数组中。字节不一定代表双精度值,双精度数组只是被用作存储机制(我意识到这很疯狂,但它是对我们框架的限制,并且我们有一个截止日期)。不过,我发现在某些情况下,将双数组复制回字节数组中时,数据已更改。将字节复制到双数组中

我已经把范围缩小到下面的测试案例失败

[TestMethod] 
    public void Test() 
    { 
     var bytes = new byte[] 
      { 
       24, 
       108, 
       6, 
       14, 
       7, 
       91, 
       242, 
       255 
      }; 

     double d = BitConverter.ToDouble(bytes, 0); 

     var returnedBytes = BitConverter.GetBytes(d); 

     for (int i = 0; i < returnedBytes.Count(); i++) 
     { 
      Assert.AreEqual(bytes[i], returnedBytes[i]); 
     } 
    } 

我现在认识到,有一些基本的框架功能阻止我采取这种方法。但是出于兴趣,任何人都可以解释为什么上述测试案例失败?

+0

您如何知道您的源代码(和您自己的处理器)正在使用哪种字节顺序? –

+0

在这种情况下,这是否重要?上述测试案例完全在内存中,在同一个处理器上,在.Net框架内。 – mattythomas2000

回答

3

因为您提供的值不是IEE754 double的有效编码 - 至少在小端架构上,这可能就是您的想法。您在上面生成的doubleNaN,这是整个范围的二进制值,不计算范围内的双倍。框架返回一个“标准”或者至少发生了变异NaN并不奇怪。

如果颠倒了32位字的排列:

7, 91, 242, 255, 24, 108, 6, 14 

您可以用4.20332332290442E-241中结束。

替代地,扭转内字节的顺序的32位字:

14, 6, 108, 24, 255, 242, 91, 7 

产量3.22903984511934E-273

最后,扭转整个列表(小结束的64位寄存器)

255, 242, 91, 7, 14, 6, 108, 24 

息率4.91380011890093E-191

所以,是的,你需要弄清楚源代码是什么,以及你自己是什么。请注意,无论您是以32位还是64位模式运行,这都可能会有所不同。

+0

这看起来像是一个有效的数字,但是字节数组来自压缩算法,所以我不认为这个数字有任何意义。我只是试图使用双数组作为存储机制,但是这显然是一个坏主意:) – mattythomas2000

+0

@ mattythomas2000为什么不使用'byte []'?将字节聚合为8字节块有什么意义? –

+0

是的,我同意,这看起来很疯狂。我们有一个可以处理double []但不能处理byte []的框架,所以我想我会尝试并且很聪明。不过,我认为解决方案是让框架处理byte []。谢谢你的帮助! – mattythomas2000

1

BitConverter并没有完全旋转位 - 它从来没有检查过它们,所以没有标准的NaN当它看到一个无意义的值时被映射。然而,JIT可能会生成代码,导致CPU与您的位进行拧紧。

如果将double放在80位寄存器中,则会发生一些隐藏的转换。在伪C中:

float80 d = *(float64*)bytes; 
*(float64*)bytes = d; 

在80位寄存器和64位存储之间的转换中,CPU会调整您的值。

相关问题