2015-08-08 39 views
1

我想檢查存儲在float類型變量中的值是否實際上是一個整數,以便我可以將它轉換爲整數類型而不會丟失數據精度。如何檢查存儲在變量中的值是否爲整數或不在c中。例如,我們在C#中有類似Integer.tryparse的東西,類似於

我的代碼

#include <stdio.h> 

#include <math.h> 

int main 

{ 

    int n; 
    scanf("%d", &n); 
    double i = log(n); 
    while(i is not an integer) 
    { 
     printf("\n Enter another number"); 
     scanf("%d", &n); 
     i = log(n); 
    } 
    return 0; 
} 
+1

你將很難找到一個整數,其「log」也是一個整數。也許你的意思是log2? – rici

+0

@rici:至少有微不足道的日誌(1)= 0 ... –

+0

@SergeBallesta:確實如此。現在再找一個:) – rici

回答

-5
int n; 
scanf("%d", &n); 
double i = log(n); 
while(i-int(i) !=0) 
{ 
    printf("\n Enter another number"); 
    scanf("%d", &n); 
    i = log(n); 
} 
return 0; 
+0

除非有足夠的理由相信浮點數完全是*整數,否則接受數字*非常接近*爲整數,對於「非常接近」的某些定義可能是個好主意。 (不是我的失望,但我猜可能是反對意見。) – rici

+0

也許downvote是因爲該代碼不會與超出整數範圍的double值一起使用。像2^33 –

-2

檢查值不isfinite或長時間和模具之間的差值大於零的不同。
這不適用於值過大的雙打,因爲它不能表示爲一個長。但是大於2^52或小於 - (2^52)的所有有限雙值都是整數,因此不需要檢查這些值。

!isfinite(i) || (i>-4503599627370496.0 && i<4503599627370496.0 && ((long)i)-i != 0) 

如果i不是整數,則以前的expresion返回true。

這隻適用於long至少53位長的架構。

對於編譯器支持long long是保證至少有64位所以這將無論工作架構的類型:

!isfinite(i) || (i>-4503599627370496.0 && i<4503599627370496.0 && ((long long)i)-i != 0) 
+0

除了'long(i)-i!= 0'部分外,這是可以的。考慮32位「長」。當然'長(4503599627370496.0/2)'是UB。 'long long'或'intmax_t'會更好。然而,C沒有具體說明這是否可行。 – chux

+0

的確,我不能假設很久會有64位。 –

+0

'long long'應該始終工作,因爲它總是至少有64位。由於&&的短路評估,只有在-2^52和2^52之間的整數纔會被轉換爲「long long」。 4503599627370496.0 = 2^52 –

0

浮點數的問題是,他們並不完全準確。如果您嘗試在十進制系統中將10除以9,那麼最終將得到一個無限數爲1的值。一個浮點數有相同的問題(除了你的計算機工作在基數2而不是10,但這真是一個細節)。由於你無法向計算機描述無數的數字,這意味着你的結果會有一些四捨五入的結果。因此,如果你做了一個複雜的計算,涉及多個操作,那麼在某些情況下,'整數'不會是一個,即使如果你要手工計算它的話。

如果您要做的是計算浮點值上的特定計算的結果是否產生整數值,則更好的方法是使用舍入值對恢復的算法進行檢查;也就是說,在這種情況下,執行輸入的log(),將結果四捨五入,然後使用適當的參數將其輸入到pow()函數。如果pow()的結果是您的輸入,那就很好。

+0

'log'的倒數是'exp'(無論如何都是C),往返也許不準確。 (正如在問題的評論中提到的那樣,有很少的整數,使得由標準庫計算的整數的自然對數的近似值也恰好是一個整數。) – rici

0

可以檢查1.

while(fmod(i,1) != 0) 

或者說模量閾值

int is_integer(double d, double threshold) 
{ 
    return d < threshold && d > -threshold; 
} 

示例如何調用

while(!is_integer(x, 1e-6)) 
3

...來檢查存儲在浮點類型變量中的值實際上是一個整數...

使用2個測試。

1)測試float value是否有小數部分:「modf函數將參數值分解爲整數部分和小數部分,每個部分都與參數具有相同的類型和符號。」這足以測試浮點值是否是整數。注意:使用modf()double

#include <math.h> 
    float ipart; 
    float frac = modff(value, &ipart); 
    if (!(frac == 0.0f)) puts("Not a whole number"). 

2)如果也轉換爲整數類型,測試如果value處於期望類型的範圍轉換之前:

#include <limits.h> 
    if (value < INT_MIN*1.0 || value > INT_MAX*1.0) puts("Outside `int` range"). 
    int y = (int) value; 
1

檢查了這一點:

#include <stdio.h> 
#include <math.h> 

int main() 
{ 
    int n; 
    scanf("%d", &n); 
    double i = log(n); 
    while(!(i == (int)i)) 
    { 
     printf("\n Enter another number"); 
     scanf("%d", &n); 
     i = log(n); 
    } 
    return 0; 
} 
+0

這適用於我,至少對我而言我在上下文中面臨一個非常尷尬的問題。所以,我不能關閉這個話題。謝謝你。 –

+0

好的,沒關係:) –

相關問題