2011-10-03 36 views
0

想象一下,我有兩個byte []數組,b1和b2,它們的字節對應兩個雙精度。 一個選擇會是這樣的......比較存儲在字節數組中的雙精度的最有效方法?

double thisValue = readDouble(b1, s1); 
double thatValue = readDouble(b2, s2); 
return (thisValue < thatValue ? -1 : (thisValue == thatValue ? 0 : 1)); 

它採用...

/** Parse an integer from a byte array. */ 
public static int readInt(byte[] bytes, int start) { 
    return (((bytes[start ] & 0xff) << 24) + 
      ((bytes[start+1] & 0xff) << 16) + 
      ((bytes[start+2] & 0xff) << 8) + 
      ((bytes[start+3] & 0xff))); 
} 

/** Parse a long from a byte array. */ 
public static long readLong(byte[] bytes, int start) { 
    return ((long)(readInt(bytes, start)) << 32) + 
    (readInt(bytes, start+4) & 0xFFFFFFFFL); 
} 

/** Parse a double from a byte array. */ 
public static double readDouble(byte[] bytes, int start) { 
    return Double.longBitsToDouble(readLong(bytes, start)); 
} 

(Apache的Hadoop的源herehere採取代碼)。

事情是,你有他們的字節表示,所以看起來很浪費,實際上他們成爲一個雙重的,但也許這是大大優化,以至於可以忽略不計。我確信Hadoop的人們知道他們在做什麼,我只是好奇爲什麼直接比較這些比特不會更好/更快?或者,也許編譯器足夠聰明,可以看到這類事情並做到這一點。

由於

回答

1

由於IEEE floating-point formatstructure,你不能簡單地檢查是否所有的位都是相同的:例如,-0和+0有不同的表示,但被認爲是相等的;和具有許多不同表示的NaN值永遠不會等於任何東西,包括具有相同表示的其他NaN值。

儘管你自己可以實現這些檢查,但它很快變得非常複雜,不值得:你需要檢查的「子值」沒有自己的字節,所以你仍然需要提取字節和把它們放入更大的值 - 然後你必須實際檢查所有不同的條件。換句話說,你最終做的和上面這段代碼做的事情是一樣的,但是你花費了更多的代碼行,你不可能比現有的代碼更好。

0

一個字節數組包含一個歸一化的雙值的位模式和用於其他包含相同值的非歸一化表示這是可能的。在這種情況下,在比較字節值將失敗的情況下,轉換和比較爲double值將會成功。

0

通過逐位比較比較浮點值有很多問題 - 例如,一個數字可能是反常數,而另一個數字可能是反常數。他們可能是「平等的」或可比的,但他們的按位表示不會。

0

身份證明說,唯一真正的方法,你會得到一個'最有效'的答案是做15-20分鐘的實驗。我真的不知道,如果使用你詳細描述的hadoop方法,將會比將byte []加載到ByteArrayInputStream並使用DataInputStream裝飾該流更快(或更多/更不精確)。 (DataInputStream所擁有.getDouble()方法)

byte[] myData = ........ 
ByteArrayInputStream bais = ByteArrayInputStream(myData); 
DataInputStream dis = DataInputStream(bais); 

double d1 = dis.getDouble(); 
double d2 = dis.getDouble(); 

讓我們知道您的基準是什麼!

相關問題