看板 C_and_CPP 關於我們 聯絡資訊
原問題是,在不調用 math.h 下,如何判斷一個浮點數是不是整數? 類似的問題還有 ceil、floor、rounding ( return (int)(x+0.5); ) 以 ceil 為例,考慮正負號、完善些的的可能長得像這樣 double ceil(double x) { if( x==(int)x) return (int)x; else if(x > 0.0) return (int)(x+1); else return (int)(x); } 而在不調用 math.h 下,判斷一個浮點數是否為整數,寫起來可能像這樣 int IsInteger(double x) { return (int)(x)==x; } 上面這些是在看 blog 時,大多人面試給的答案,但我認為不算正確 ( 當然我不是面試官,我不知道他們是怎麼評量這些答案的 ) 用 cast 達到 ceil、floor、rounding、判斷整數還蠻常見的, 但我認為錯誤的關鍵是在於這種寫法完全乎視了 casting 所帶來之影響, 換句話說,上述任一函式,將 x 以 12345678901234567890.12 傳入, 這在 casting 時必會發生 error,造成不可預期之錯誤。 問題來了,我也不知道真正標準的,「判斷整數」、「模擬 ceil」,該如何做, 初步是有想過以 IEEE754 64bits 方式下去分析,但卻又一直想不透, 不知各位版友對於此問是否有其他想法? 謝謝各位不吝解惑。 -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.78.41 tropical72:轉錄至看板 Programming 09/28 00:00
VictorTom:一定要回避cast可能造成的問題的話, 小弟我想到的方式也 09/28 00:03
VictorTom:是直接抓IEEE754的浮點表示法, 解出exponent與mentisa出 09/28 00:03
VictorTom:來算, 理論上可以藉由bit expression找到一個rule來判斷 09/28 00:04
VictorTom:一個浮點數是否為整數; 限定用754表示法儲存的數就是了. 09/28 00:04
alongalone:不用library, 那你從資料結構下手吧....自己把double 09/28 00:04
alongalone:從新組合成integer 的格式 09/28 00:05
VictorTom 與 alongalone 所提之方式與小弟想到的有同曲之妙, 唯目前即使以 unsigned long long * 去接出來,還是讓人感到難以著手。 ( 在想這應也是一小段演算法了吧 ? ) 想過方式為,先取得 B=2^(exp-basement),假設 matissa = 111101... 再以 (1+0.5) * B, (1+0.75) * B, (1 + 0.875) *B, 再去判斷最大可能之整數, 問題又落回去了, 「判斷浮點數為整數」。 ※ 編輯: tropical72 來自: 180.177.78.41 (09/28 00:10)
ericinttu:好久好久沒看到這個浮點表示法了ORZ 發言之前先複習一下 09/28 00:12
VictorTom:小弟以為, 計算exponent的值, 是否足以讓mentisa shift 09/28 00:16
VictorTom:到成為1.xxxxxxxx(x為0or1)的正規表示式後, 小數點.之後 09/28 00:17
VictorTom:全為0, 是的話即代表該數為整數(先不考慮超小數)@_@" 09/28 00:17
VictorTom:所以應該不用去算出浮點數來, 計算bit位數應該就行了@@" 09/28 00:18
ericinttu:跟VictorTom想法一致 09/28 00:20
ericinttu:mentias 有幾個bits, 最多就是需要左shift幾次. 09/28 00:26
tropical72:真的是晃然大悟!這樣 ceil/floor 也可類似搞出來了. 09/28 00:27
tropical72:感謝各位. 09/28 00:27
ericinttu:用簡單的說法(假如有講錯請鞭) 09/28 00:29
ericinttu:IEEE754 是 1+8+23 bits. mentisa 用到左邊數來第幾位, 09/28 00:31
ericinttu:它的exponent值就要有多少. 09/28 00:32
ericinttu:有一些特例/邊界值, 可能要另外考慮 (還沒有檢查那些) 09/28 00:33
tropical72:嗯,這樣效率變 find most right bit 問題,可解.感謝!! 09/28 00:37
ericinttu:特例情況是指 http://zh.wikipedia.org/wiki/IEEE_754 09/28 00:56
ericinttu:32位單精度之下, 零/負零/... 等等的情況都要考慮到. 09/28 00:57
cutecpu:http://codepad.org/L5qDMZdg 09/28 01:16
tropical72:謝謝 cutecpu, 補上union http://codepad.org/Sixd4u0n 09/28 01:38
firejox:請愛用sprintf~~ 09/28 01:52
tropical72:sprintf ? 字串分析嗎? 09/28 01:53
tropical72:sprintf(buf, "%.16e", x); 再分析 buf 嗎?不就慢了? 09/28 01:54
firejox:恩恩 是的 09/28 01:54
tropical72:sprintf 確實也為一種解法便是, 謝謝 firejox 提供 ^^ 09/28 01:55
firejox:可是能夠完善處理總比出錯好呀~~ 09/28 01:56
tropical72:確實可能較完善,只是在面試這回答恐怕.. 09/28 02:09
※ 編輯: tropical72 來自: 180.177.78.41 (09/28 02:09)
littleshan:sprintf要小心buffer overflow唷 09/28 02:48