質問

の問題を導出するために式を決定する桁数に定数が与えられた。

例えば: には十進数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);
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top