どのように多くの桁にはこのマネタリーベースとしたのか
質問
の問題を導出するために式を決定する桁数に定数が与えられた。
例えば: には十進数100006で表すことができる17,11,9,8,7,6,8桁のための基2,3,4,5,6,7,8ます。
の式で得たことは以下のようになっています:(log10(num)/log10(ベース))+1.
C/C++を使ってこの式を計算するため、上記されます。
long long int size = ((double)log10(num) / (double)log10(base)) + 1.0;
ところが、式がないことを前提とする正しい答えをする場合には、このような:
Number 8 in base 2 : 1,0,0,0
Number of digits: 4
Formula returned: 3
Number 64 in base 2 : 1,0,0,0,0,0,0
Number of digits: 7
Formula returned: 6
Number 64 in base 4 : 1,0,0,0
Number of digits: 4
Formula returned: 3
Number 125 in base 5 : 1,0,0,0
Number of digits: 4
Formula returned: 3
Number 128 in base 2 : 1,0,0,0,0,0,0,0
Number of digits: 8
Formula returned: 7
Number 216 in base 6 : 1,0,0,0
Number of digits: 4
Formula returned: 3
Number 243 in base 3 : 1,0,0,0,0,0
Number of digits: 6
Formula returned: 5
Number 343 in base 7 : 1,0,0,0
Number of digits: 4
Formula returned: 3
ではエラーによる1が完了します。いったい誰か教えてくれるので助かります正式な仕事である。
編集: り、入力仕様のまったような場合10000000000ます。e10^10というのはありえないと考えlog10()はC/C++対応できるようなケースはどうでしょうか。その他の手順/公式をこの問題お願い申し上げます。
解決
が高速浮動小数事業のコンパイラを設定します。必要な精密floationます。ものであるlog10(8)/log10(2)は常に3math.だが結果は2.99999、expample.です。いてくれるものでなければなりませ小添加剤な±0.5℃です。すべきである.00001があります。
ほぼ真式:
int size = static_cast<int>((log10((double)num) / log10((double)base)) + 1.00000001);
本当に真のソリューション
を確認しておきましょう、結果の式です。Compexityは O(log log n)
または O(log result)
!
int fast_power(int base, int s)
{
int res = 1;
while (s) {
if (s%2) {
res*=base;
s--;
} else {
s/=2;
base*=base;
}
}
return res;
}
int digits_size(int n, int base)
{
int s = int(log10(1.0*n)/log10(1.0*base)) + 1;
return fast_power(base, s) > n ? s : s+1;
}
このチェックがより力試験 base
掛け算を含む比較中
他のヒント
次のいずれかが動作します。
>>> from math import *
>>> def digits(n, b=10):
... return int(1 + floor(log(n, b))) if n else 1
...
>>> def digits(n, b=10):
... return int(ceil(log(n + 1, b))) if n else 1
...
最初のバージョンは mathpath.org から説明します。第二のバージョンに+ 1
は、任意の数のために正しい答えを得るために必要である N B D の塩基の桁との最小の数です。それは、書かれているこれらの数字は、の10 ... 0 のベースでのB のです。入力0
特別なケースとして扱われなければならないことを確認します。
小数点例:
>>> digits(1)
1
>>> digits(9)
1
>>> digits(10)
2
>>> digits(99)
2
>>> digits(100)
3
バイナリます:
>>> digits(1, 2)
1
>>> digits(2, 2)
2
>>> digits(3, 2)
2
>>> digits(4, 2)
3
>>> digits(1027, 2)
11
編集:OPはlog
ソリューションは、大入力に対して動作しない可能性があることを述べています。それが唯一の(Cでこの時間)整数演算を使用しているので、私はそれについて知らないが、もしそうであれば、次のコードは、壊すべきではありません。
unsigned int
digits(unsigned long long n, unsigned long long b)
{
unsigned int d = 0;
while (d++, n /= b);
return d;
}
このコードは、おそらくあまり効率的になります。そして、のはいの、それが最大のあいまいポイントのために書かれました。これは単に、すべての数は、少なくとも一桁を有する観察を使用し、b
を生じない0
によって毎divisonという追加の桁が存在することを意味しています。より読みやすいバージョンは、次のされます:
unsigned int
digits(unsigned long long n, unsigned long long b)
{
unsigned int d = 1;
while (n /= b) {
d++;
}
return d;
}
(私はちょうどそれを試してみました)、私は数はそれがあるべき整数値よりもわずかに小さいことが原因、それはあなたの部門の丸め誤差だと思うだろう。あなたは整数に切り捨てたときに(つまり切り捨てが実際にラウンド演算であるので)だから、あなたは1試し、最終的な値に追加0.5を追加を失います。
何が欲しいの天井(=最小の整数より大きくないが)<サブ> B サブ>(N + 1)、むしろ、あなたが今計算しているものよりも、床(1 +ログ<サブ> Bを記録していますサブ>(N))
あなたは試してみてください。
int digits = (int) ceil( log((double)(n+1)) / log((double)base) );
は、エラーを丸めているが、提案されたソリューションは、単に危険地帯を移動したり、それは小さく、彼らはそれがなくなるわけではありませんします。あなたの数字が整数であるなら、あなたは確認することができます - のの整数演算を使用して - ベースの1つの電力がより少ないか、あなたの数に等しく、次は(最初のパワーがそれを上回っていること桁数)。あなたがチェーンのどこにも浮動小数点演算を使用している場合(あなたのベースは多分、2つのパワーであり、しない限り)しかし、その後、あなたがエラーに対して脆弱になります。
編集の
ここで整数演算で粗だが効果的な解決策です。お使いの整数クラスがベース*の数ほどの大きな数字を保持することができた場合は、これは正しい答えが得られます。
size = 0, k = 1; while(k<=num) { k *= base; size += 1; }
あなたの数式を使用して、
log(8)/log(2) + 1 = 4
問題は、対数計算の精度です。使用
ceil(log(n+1)/log(b))
その問題を解決するべきです。これは、
と全く同じではありませんceil(log(n)/log(b))
これは、n = 8、B = 2のための答え3を与えるので、またそれは
と同一でありますlog(n+1)/log(b) + 1
は、これがnの回答4を与えるので= 7、B = 2(完全精度で計算した場合)。
私は実際にいくつかの好奇心を実装し、++グラムで最初にフォームをコンパイルした取得ます:
double n = double(atoi(argv[1]));
double b = double(atoi(argv[2]));
int i = int(std::log(n)/std::log(b) + 1.0);
(IEが答え3を与える)が失敗し、しばらく、
double v = std::log(n)/std::log(b) + 1.0;
int i = int(v);
成功(答4を提供します)。それを見てみると、いくつかのより多くの私が考える三番目の形式
ceil(log(n+0.5)/log(b))
(第2の形態のために+ 1またはN)場合、それは「クリティカル」の場合を回避するため、、より安定であろう(nは整数値の)Bの整数乗である。
どこかにあなたのコードに丸め機能(例えば+ 0.5)をラップすることが有益であり得る:それは部門が生産されていることは非常に可能性があります(例)2.99989787、それはint型に変換されますとき1.0は、追加3.99989787を与えるとされるためにどの、それは3を与えます。
は、式が私に右であるように見えるます:
Number 8 in base 2 : 1,0,0,0
Number of digits: 4
Formula returned: 3
log10(8) = 0.903089
log10(2) = 0.301029
Division => 3
+1 => 4
だから、それは間違いなくだけで丸め誤差です。
浮動小数点の丸めの問題ます。
log10(216) / log10(6) = 2.9999999999999996
しかし、提案として、それは次のために動作しませんので、あなたが、0.5を追加することはできません。
log10(1295) = log10(6) = 3.9995691928566091 // 5, 5, 5, 5
log10(1296) = log10(6) = 4.0 // 1, 0, 0, 0, 0
たぶん、これらの丸め誤差を回避するログ(値、ベース)関数を使用します。
私は丸め誤差が他のエラーを生成せずに解消を取得する唯一の方法は、整数の対数を使用するか、実装することだと思います。
ここではbashでのソリューションです。
% digits() { echo $1 $2 opq | dc | sed 's/ .//g;s/.//' | wc -c; }
% digits 10000000000 42
7
static int numInBase(int num, int theBase)
{
if(num == 0) return 0;
if (num == theBase) return 1;
return 1 + numInBase(num/theBase,theBase);
}