将字节复制到双数组中

时间:2013-10-07 16:03:48

标签: .net c#-4.0

我正在尝试将字节流复制到双数组中。字节不一定代表double值,double数组只是用作存储机制(我意识到这很疯狂,但它是我们框架的当前限制,我们有一个截止日期)。但是我发现在某些情况下,当将双数组复制回字节数组时,数据已经改变了。

我已将其缩小到以下测试用例失败

[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]);
        }
    }

我现在意识到有一些底层框架功能阻止我采用这种方法。但是,出于兴趣,任何人都可以解释为什么上述测试用例失败了吗?

2 个答案:

答案 0 :(得分:3)

因为你提供的值不是IEE754双倍的有效编码 - 至少在little-endian架构上,这可能就是你所拥有的。您在上面生成的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位模式下运行,这都可能会有所不同。

答案 1 :(得分:1)

BitConverter根本不会涉及这些位 - 它甚至从不检查它们,因此当它看到无意义的值时,没有标准的NaN被映射。但是,JIT可能会生成代码,导致CPU与您的位拧紧。

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

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

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