2013-10-07 121 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會調整您的值。

相關問題