2016年7月29日金曜日

数字の桁数を取得する方法

数字の桁数を取得する関数って意外とない。。
結構使うものだと思うんだけど、なんで提供されてないんだろ?
備忘録にまとめとく


 数字を文字列に変換して「文字数=桁数」で求める方法
多分一番よく使われる方法だろう
数字がある程度の大きさの自然数の場合、数字を文字列に変換すると文字数と桁数が一致する

Javaの場合
// num = 365を文字列に変換し、文字数から桁数を求める
int num = 365;
int length = Integer.toString(num).length();
System.out.println(num + "の桁数は" + length);
Cの場合
// num = 365を文字列に変換し、文字数から桁数を求める
#include <stdio.h>
int num = 365;
char char_num[100];
int length = sprintf(char_num, "%d",num);
特徴
  • よく使われててわかりやすい
  • 負の数の場合、マイナスが1桁としてカウントされる
  • 実数の場合、小数点も1桁としてカウントされる
  • 実数の場合、小数点以下も桁としてカウントされる
  • 大きい数字の場合、数字リテラルで文字変換されるため、桁が合わない
  • 例)long num = 10E10;を文字列変換すると String num_string = "10E10";になる
  • フォーマット依存
  • 例1)10.00 ⇒ 5桁扱い
    例2)1.0E2 ⇒ 5桁扱い

基本int型の桁数知りたければ、この変換方で十分
※マイナスには注意

 常用対数を利用して求める
高校数学でやったことあるだろう。対数を使って数字の桁数を計算する方法
正の実数$x$が$n$桁の数だとすると
\[ 10^{n-1} \leq x < 10^{n} \\ \Leftrightarrow n-1 \leq \log_{10} x < n \] 高校数学だと、ここまで分かれば解は出るけど、
プログラムを楽に組むために、ちょっと変形する。 上記不等式に1を加える
\[ \Leftrightarrow n \leq \log_{10} x + 1 < n +1 \] 左辺と中辺について、イコールが成立するときを考えると、
中辺の小数点を切り捨て(丸め誤差)たとき成立する
\[ n = \lfloor {\log_{10} x + 1} \rfloor =\lfloor {\log_{10} x} \rfloor + 1 \] これで桁数を求める数式が出来上がった
よって、プログラムで書くと

javaの場合
// 対数から桁数を求める
int num = 365;
int length = (int)Math.log10(num) + 1;
System.out.println(num + "の桁数は" + length);
Cの場合
// 対数から桁数を求める
#include <math.h>
int num = 365;
int length = (int)log10(num) + 1;
特徴
  • あまり見ない。。理系じゃないと読めないから
  • 負の数の場合、対数関数は正常動作しない
  • 負の桁数が知りたい場合は絶対値(abs関数)で補う必要がある
  • 実数の場合(1以上)、小数点以下はカウントされない
  • 実数の場合(1以下)、負の値を返す
  • 0.000001を変換すると、-5になる。何桁目から数字が表示されるかを表している

数学的な桁数を知りたい場合に有効
1より大きい場合なら、小数や巨大な数字でも正確な桁数を求めることができる

応用して、N進数の桁数の取得方法「数字の桁数を取得する方法(2進数ver)

0 件のコメント:

コメントを投稿