2010-04-30 136 views
1

在C的美好時代,我可以將float轉換爲int(假設爲32位系統),執行一些位操作(按位和右移等) ),並獲得浮點數的高16位和低16位十六進制表示,然後我可以將它們存儲在兩個短值中。我在C#中看不到一個簡單的方法。在.NET中將Single轉換爲兩個UInt16值

System.Convert.ToUInt16只是做一個浮點數到int轉換(即使在我右移之後),如果浮點數小於0,則該值爲0,這不是所需的效果。

//Useless leaves me with a value of 0 
UIN16 s1 = (UInt16)((System.Convert.ToUInt32(d2) & 0xffff0000) >> 16); //Capture the high word 
UInt16 s2 = (UInt16)(System.Convert.ToUInt32(d2) & 0xffff);    //Capture the low word 

基本轉換(UInt32)也不起作用。

+0

在C#的更好的新的一天,我們更清楚地知道我們如何轉換;-) – 2010-04-30 18:19:48

回答

0

有類BitConverter它有一些不錯的和有用的方法。

例如,方法GetBytes可以將許多不同類型的變量轉換爲字節數組,並且方法ToUInt16返回從字節數組中指定位置的兩個字節轉換而來的16位無符號整數。

1

最接近的直接等同於你的C方法將是不安全的代碼要做到這一點,和指針:

private static unsafe void SplitToWords(float f, out ushort s1, out ushort s2) 
{ 
    unsafe 
    { 
     float* ptr = &f; 
     UInt16* s2ptr = (UInt16*) ptr; 
     UInt16* s1ptr = s2ptr + 1; 

     s1 = *s1ptr; 
     s2 = *s2ptr; 
    } 
} 

這讓你做:

public static void Main() 
{ 
    float f = -23984.123f; 
    ushort s1; 
    ushort s2; 
    SplitToWords(f, out s1, out s2); 

    Console.WriteLine("{0} : {1}/{2}", f, s1, s2); 
    Console.ReadKey(); 
} 

但是,更常用的管理方式是使用BitConverter

byte[] fBytes = BitConverter.GetBytes(f); 
s1 = BitConverter.ToUInt16(fBytes, 2); 
s2 = BitConverter.ToUInt16(fBytes, 0); 

你可以看到這些產品在這裏同樣的事情:

public static void Main() 
{ 
    float f = -23984.123f; 
    ushort s1; 
    ushort s2; 
    SplitToWords(f, out s1, out s2); 

    Console.WriteLine("{0} : {1}/{2}", f, s1, s2); 

    byte[] fBytes = BitConverter.GetBytes(f); 
    s2 = BitConverter.ToUInt16(fBytes, 0); 
    s1 = BitConverter.ToUInt16(fBytes, 2); 
    Console.WriteLine("{0} : {1}/{2}", f, s1, s2); 

    Console.ReadKey(); 
} 
0

簡短的回答:不這樣做!

很長的解釋:在過去的美好時代,這些黑客行爲已經完成了,因爲執行float到int轉換(反之亦然)比讓FPU完成這項工作快得多。我可能是錯的,但我想我記得PC遊戲Descent(任何人都記得它? - 很好的Quake 1天)的這種優化的成功故事。在這種情況下,它產生了30%的差異。至少我是這麼記得的。

現在這已經不是真的了,其實事實恰恰相反。如果您針對舊版x86 FPU編譯代碼,則必須以整數單位完成任何位操作,並且每次從float到int單位的轉換都必須通過內存完成。這花費了週期的批次。您通常不會混合具有相同值的float和int操作,並且CPU未針對此用例進行優化。

另一方面,如果將代碼編譯爲SSE指令集,則可以採用快捷方式。在浮點數據上進行整數運算沒有額外的成本,反之亦然,但是直接int < - >通過SSE的浮點數轉換首先要快,所以爲什麼要麻煩呢?

它在其他體系結構中變得更糟..在ARM Cortex-A8上,舉例來說,這樣的技巧會使整個CPU停頓至少21個週期......我讀過關於混合int和浮點數的恐怖故事PowerPC (加載/修改/存儲任何人?)

總結:除非您爲Pentium-I傳統硬件編寫,否則不要這樣做。如果是這樣,請聯繫我;我的硬盤上仍然有所有的時間和示例代碼。