[ 題目 ]

這題目大多以口試型態出現,其它類似的題目包含了 ceil、floor。

 

int is_integer(double x)
{
    /* if x is a integer, return 1 */
    /* else return 0 */
}

 

 

[Sol]

 

一般的寫法   return x==(int)x;

這寫法若出現在大學、碩士、新鮮人的面試,我認為算是不錯的答案了。

 

考慮一下 x = 2200000000.0 的時候會發生什麼事...

 

不少人認為可以用 stringstream / sprintf 方式,

再做 string compare ,我只能說精度是 15.22 位,

至於是不是真的無誤,我保留態度 ( 我是覺得 "不完全" 正確 )。

 

這方法麻煩了點...

 

#define DBL_MAT_BITS 52
#define DBL_SIGN_MASK 0x8000000000000000ULL
#define DBL_EXP_MASK 0x7ff0000000000000ULL
#define DBL_MAT_MASK 0x000fffffffffffffULL
#define DBL_BASE_VALUE 1023

int is_int(double x)
{
     unsigned long long v    = *(unsigned long long *)&x;
     unsigned long long mat  =  ( v & DBL_MAT_MASK );
     int exp  = (int)((v & DBL_EXP_MASK ) >> (DBL_MAT_BITS))-DBL_BASE_VALUE;

     if(v==DBL_SIGN_MASK || v==0ULL) return 1;
     if(exp < 0) return 0;
     mat<<= (DBL_MAT_BITS + exp);
     return mat==0ULL;
}

 

用到很多 macro,看起來麻煩很多。關於上述定義的 macro,其實去查 float.h 裡面的 DBL_MANT_DIG (查到記得扣1),再配合 sizeof(double)、CHAR_BITS,所有資訊都調得出來。

 

其實之前曾發過一篇文章,[浮點數] C 語言 ceil / floor 取代方案之謬誤,裡面有針對這問題做解釋,只是每次看到有人建議,不要用 C library 裡面的 ceil、floor 時,不免會暗自竊笑 : 知道要寫正確、又要寫贏 compiler 自己寫的,要花多少功夫嗎?

edisonx 發表在 痞客邦 PIXNET 留言(0) 人氣()