在Redis(http://code.google.com/p/redis)中將雙精度轉換爲整數以便將元素與元素相關聯,以便將此元素進行排序。即使許多用戶實際按整數排序(例如unix時間),該分數也是雙打的。爲了獲得速度
當數據庫被保存時,我們需要寫這個雙打ok磁盤。這是目前使用的內容:
snprintf((char*)buf+1,sizeof(buf)-1,"%.17g",val);
此外還會檢查無窮大和非數字條件,以便在最終的數據庫文件中表示該條件。
不幸的是,將double轉換爲字符串表示法很慢。雖然我們在Redis中有一個以更快的方式將整數轉換爲字符串表示形式的函數。所以我的想法是檢查一個double是否可以被轉換成一個整數而不丟失數據,然後如果這是真的,則使用該函數將整數轉換爲一個字符串。
爲了提供一個很好的加速,當然整數「等價」的測試必須是快速的。所以我使用了一種可能未定義的行爲,但在實踐中效果很好。類似的東西:
double x = ... some value ...
if (x == (double)((long long)x))
use_the_fast_integer_function((long long)x);
else
use_the_slow_snprintf(x);
在我的推理上面的double casting將double轉換成long,然後返回到整數。如果範圍適合,並且沒有小數部分,則該數字將在轉換後存活,並且與初始數字完全相同。因爲我想確保這不會破壞某些系統中的某些東西,所以我加入了freenode上的#c,並受到很多侮辱;)因此,我現在正在嘗試這裏。
有沒有一種標準的方法來做我想要做的事情,而不需要去ANSI C之外?否則,上述代碼是否應該適用於當前Redis所針對的所有Posix系統?也就是說,Linux/Mac OS X/* BSD/Solaris現在正在運行的拱?
爲了使代碼更加完整,我可以添加的內容是在嘗試執行演員之前明確檢查雙精度的範圍。
謝謝你的幫助。
侮辱侮辱,男人。我不知道答案,但我希望你找到答案。 – mmr 2010-05-12 17:06:03
如果有幫助,http://stackoverflow.com/questions/638376/what-is-the-most-reliable-way-of-checking-if-a-floating-point-variable-is-an-inte was a在C#中檢查這種方式。我還沒有找到一個C版本。 – 2010-05-12 17:15:13
或者,我可以使用modff()來檢查小數部分是否爲零?然後檢查整體部分的範圍是否在很長的範圍內,如果屬實,則施放它。 – antirez 2010-05-12 17:43:39