2015-04-24 76 views
6

我正在處理不同基數(base-10,base-8,base-16等)中的數字。我正在計算每個數字中的字符數。如何計算不同基數中數字的位數?

編號:ABCDEF

位數:

我知道基於對數的方法,但我面臨的一些問題。

  1. This Python script輸出,未能在3969號正確計算的位數了100萬。

  2. 我認爲使用對數的方法可能是相當緩慢的

鏈接:

  • This C program必須非常緩慢(如果我有一個非常大的數字?)。它也不能處理不同基地的數字(例如,基數爲16)。

  • 不是this愚弄的人,因爲在OP問只有約基10


編輯:當然我可以計算一個字符串的長度,但什麼更吸引我,是否有可能進行沒有約定的字符串。我想知道的算法,可以幫助做到這一點只知道源基地的基地轉換爲

EDIT2:源基基10的要轉換爲可以是任何其他鹼基。


我們如何計算不同基數的數字位數?

如果我知道基數爲10的數字,如何計算轉換爲基數爲16(base-8等)的相同數字中的數字位數而不執行轉換

:一些Python或C代碼將不勝感激

+0

只是一個想法,在給你寫一個完整的答案之前,應該像這樣的一個方法滿足你:找到所需的能力,例如16^n> your_number> 16^n,因爲那麼數字的數目應該是類似的n ... –

+1

你問我們如何調試你的Python腳本嗎? – abarnert

+0

@EmmanuelJay,我認爲任何足夠快的方法都適合。 – ForceBru

回答

8

對數應該不會太慢。您可以通過以下公式輕鬆計算任意基數的對數:logBaseN(x)=logBaseA(x)/logBaseA(N) - 您可以使用ln(基數e = 2.718 ...)或logBase10或任何您擁有的基數。所以你並不真的需要一個程序,一個公式推應該這樣做:

num_digets(N, base) = 1 + floor(log(N)/log(base)) 

其中N是你的號碼,base要在這個數字基礎

更多解釋在這裏看看: http://www.mathpath.org/concepts/Num/numdigits.htm

+0

谷歌設法隱藏這個鏈接,我現在要調查它 – ForceBru

1

我不知道我理解你的問題。當你說你的初始數字是以b1爲基數的時候,這是否意味着你有一個基數爲b1的字符串表示?也許你想要建立一些表格,告訴你基數b1中的哪個數字對應於b2,b2^2,b2^3,...然後將您的號碼與這些數字進行比較,以查看它適合的位置。

否則,我會去你提到的算法,這可以很容易地採用任何基地。

輸入:你的整數x,B2要在計算數字的基礎

int number_of_digits (int x, int b2) { 
    int n = 0; 
    while (x >0) { 
     x/=b2; 
     n++; 
    } 
    return n; 
} 

兩種方法都只是n的線性。

編輯:如果您希望速度更快,您可以將其實現爲二分查找。然後你可以得到O(log(n))。

2

注意Python代碼你NumToStr()功能是不正確因您的基地關閉的情況的一個,它應該是:

def NumToStr(num): 
    str='' 
    while num: 
      str+=alpha[(num)%base] 
      num=(num)/base 
    return ''.join(list(reversed(str))) 

請注意,檢查此函數是否返回正確的結果會發現錯誤(例如,使用alpha="")。

用此修復程序,我們得到使用給定公式的小數位數正確:

nDigits = int(ceil(log(nmb, base))) 

除了爲基礎的確切權力(base**0base**1base**2,等...),它在哪裏恰恰比應該少一個。

nDigits = 1 + floor(log(nmb, base)) 

注意,即使這似乎失敗某些輸入(例如,從變換鹼基10至鹼基10它錯誤地說3位爲1000個6位:這可以通過稍微改變forumla被固定爲1000000)。這似乎是由於浮子的固有inprecision,例如:

print floor(log(1000, 10)) 

輸出2而不是預期的3

關於您提到的性能問題,我不會擔心這些微不足道的代碼的性能問題,除非您完成了分析/基準測試,證明它是一個問題。例如,對於一個128位的數字,你的「非常慢」的C代碼最多隻需要38個分區乘以10。如果你需要比這更好的性能,那麼你會遇到同樣的問題與這裏提到的任何微不足道的方法。我能想到的最快的事情是自定義log()函數,它使用查找表和線性插值的組合,但您必須小心所產生的精度。