2013-04-16 63 views
-1

有沒有任何數學或算法的方法將浮點數分成兩部分(之前和之後)。從浮點數中分離小數的算法或數學方法?

例子:

number=456.789 
before=456 
after=0.789 

我不希望任何代碼,因爲我可以在任何編程語言做到這一點。我想要一個通用算法,最好使用算術或其他這樣的操作符。

+3

您是否希望我們在內存中考慮IEEE754浮點表示?我們可以使用數學函數天花板和地板嗎? –

回答

4

這一切都取決於什麼操作都可以在浮點值:

  • ,如果你有floorceil,那麼你可以使用其中的一個來獲得的整數部分,和減法得到的小數部分。
  • 如果你有除法餘數,你可以做到這一點(使用1作爲除數)。
  • 如果您可以檢查值的位表示,知道哪些位是指數和尾數,那麼您可以使用它。
  • 如果您可以將該值視爲十進制字符串,則可以拆分小數點分隔符(通常爲.,),但科學記數法需要額外的工作來處理。
  • 如果您只有比較,加法和減法,那麼您可以對整數部分進行二分法搜索 - 通過一系列指數增加的猜測來確定起始邊界。從某種意義上講,這可能是最「通用」的,因爲它只是假設有序加法羣的基本數學運算(因爲如果你關心的話可以避免乘法或除法)。但不可思議的是,會有一種嚴重的浮點編程語言,不能提供更高效的方式。
+0

「floor」和「ceil」失敗,除非它們以符號爲條件。例如,用普通的'double',應用'before = floor(x);在-0x1p-54之後,將會產生-1和1,當結果應該是0和-0x1p-54或-1時,根據需要,不可表示的值將略小於1。使用'trunc'或'fmod'更合適。 –

+0

@EricPostpischil:同意了,當然這是給需要使用任何特定語言編寫代碼的人的正確建議。我只是不知道'trunc'或'modf'是否被計爲「我不想要任何代碼」,因爲它們被專門定義爲返回(其中一個)所需的值。 –

+0

@SteveJessop:+1,但你的二進制搜索可以改進。 floor(x)必須在(x-1,x)的範圍內,所以不需要進行指數猜測(你會搜索什麼?)。但是,到底什麼時候到達地板,你到底知道些什麼?你是否找到一個沒有乘法或除法的中點?(是的,我知道OP需要trunc(),而不是floor(),但通過使用絕對值很容易解決。) – rici

1

我通常做以下讓你問什麼:

double number=456.789; 
int before= number; //This type cast is equivalent to floor(number) 
double after=number-before; 

因此獲得給定的浮點數的地板是我們正在執行的主要任務,其中地上方法只返回最大整數不大於輸入數字。這很可能是通過在存儲器中利用floating point representation進行某些語言級別的操作(因爲未定義,您無法在浮點數中執行正常的按位運算)。 因此,AFAIU,如果你不想使用地板/類型,你基本上是註定要失敗的。