2010-11-10 42 views
5

的「字符串長度」基本上我想回到在INT的位數 - >值是這樣的:找到一個int

(int)1 => 1 
(int)123 => 3 
(int)12345678 => 8 

我一無所知C,所以請多多包涵。我知道目標c,但我使用整數和浮點數來代替NSNumber。我意識到我可以將這些int轉換成客觀的c對象,但是這看起來很不舒服,如果我可以用C來做,我將會知道它的未來。

感謝

回答

22

使用

int d = (value == 0 ? 1 : (int)(log10(value)+1)); 

需要注意的是負數,這並不工作,你將不得不使用

int d = (value == 0 ? 1 : ((int)(log10(fabs(value))+1) + (value < 0 ? 1 : 0))); 

其中a如果value爲負數,則爲dds 1爲負號。

+0

謝謝你馬丁。 +1給我0和減號。 :) – 2010-11-10 09:45:29

+0

+1對於相同的 – DVK 2010-11-10 09:46:05

+2

(值<0?1:0)等於(值<0) – Vovanium 2010-11-10 11:57:06

5

使用對數基10:

int length = (int)floor(log10((float)number)) + 1; // works for >0 
+0

非常感謝。 :) – 2010-11-10 09:45:09

1

一個更通用的解決方案,特別是如果你想知道的長度與printf()變種印刷的目的是:

snprintf(NULL, 0, "%d", myint); 

返回值應該告訴你,將要打印的字符串的長度。

+0

@pst:你爲什麼要剪掉'\ 0'部分? – aib 2010-11-10 18:58:48

+0

NUL不包含在字符串長度中,只是作爲一個C字符串。 (這只是使用的措辭。) – 2010-11-11 04:29:32

10

可能比使用日誌或INT-到字符串的轉換,並且不使用任何庫函數快很多是這樣的:

int nDigits(int i) 
{ 
    if (i < 0) i = -i; 
    if (i <   10) return 1; 
    if (i <  100) return 2; 
    if (i <  1000) return 3; 
    if (i <  10000) return 4; 
    if (i <  100000) return 5; 
    if (i < 1000000) return 6;  
    if (i < 10000000) return 7; 
    if (i < 100000000) return 8; 
    if (i < 1000000000) return 9; 
    return 10; 
} 

編輯後,傑夫·耶茨的擔憂:

對於那些擔心誰有關int大小不同於32位 (類似於pmg的解決方案,但仍然更快,因爲乘法比分區更快:-)

#include <limits.h> 

#define PO10_LIMIT (INT_MAX/10) 


int nDigits(int i) 
{ 
    int n,po10; 

    if (i < 0) i = -i; 
    n=1; 
    po10=10; 
    while(i>=po10) 
    { 
    n++; 
    if (po10 > PO10_LIMIT) break; 
    po10*=10; 
    } 
    return n; 
} 
+1

+1爲最快的算法 – pmg 2010-11-10 10:57:58

+0

這隻有在int是32位值時纔有用。由於'int'的大小依賴於C和C++平臺,所以我不會依賴這個。 – 2010-11-10 18:20:44

+0

@Jeff Yates:我知道!但是,如果這真的是一個問題,只需添加/刪除一些指令。如果你真的需要一個適用於不同平臺的解決方案,你可以使用#if測試特定int類型的大小,或者使用pmg的解決方案(仍然可以優化)。 – Curd 2010-11-10 20:32:29

4

這裏的另一種選擇

int nDigits(unsigned i) { 
    int n = 1; 
    while (i > 9) { 
     n++; 
     i /= 10; 
    } 
    return n; 
} 

這比使用log10快,但比豆腐與級聯測試選項慢。然而,它不承擔int s爲32位:-)

1

如果你的整數值(例如12345678u)是一個編譯時間常數,你可以讓編譯器確定你的長度:

template<typename T> 
constexpr unsigned int_decimal_digits(T value) 
{ 
    return ( value/10 
        ? int_decimal_digits<T>(value/10) + 1 
        : 1); 
} 

用法:

unsigned n = int_decimal_digits(1234); 
// n = 4 

#include <limits.h> 
unsigned m = int_decimal_digits(ULLONG_MAX); 
// m = maximum length of a "long long unsigned" on your platform 

這樣,編譯器會自動計算出小數號碼,和值作爲一個恆定的填充。它應該是最快的解決方案,因爲不涉及運行時計算,並且通常將整型常量放入指令操作碼中。 (這意味着它們通過指令流水線傳輸,而不是通過數據存儲器/緩存傳輸。)但是,這需要一個支持C++ 11的編譯器。