#076
posted on 2022.06.17 (Fri)

桁の大きな数値を万進の表記に変換して表示。

SNSなどのAPIから取得したフォロワー数や再生数などを表示するときに、「123456789」を「1億2345万6789」など、桁数が多い場合に日本の命数法である万進の形式で表示したかったので、JavaScriptとPHPで実装した方法のメモ。

 

万進

日本では、1627年(寛永4年)の『塵劫記』の初版において初めて大きな数が登場するが、極以下が下数、恒河沙以上を万万進の中数としていた。1631年(寛永8年)の版では極以下が万進(恒河沙以上は万万進のまま)に改められ、それとともに算学啓蒙・算法統宗にあった不可思議の上の無量数も無量大数という名称として組み込まれた。そして1634年(寛永11年)の版ではすべて万進に統一された。今日でも万進だけが使用されている。(Wikipedia)

 

 

JavaScriptで変換処理する場合

JavaScriptで、数値に万進の単位を挿入した文字列に変換する関数を作成して、引数に数値を指定して実行する方法。

 

変換する関数を作成

引数で受け取った値を、桁数に応じて万進の単位を挿入した文字列に変換して返す関数を作成する。

  1. 引数で渡された値が数値として扱えるかチェック。(数値に変換できない文字列の場合はエラー処理。)
  2. 各万進の単位の頭が「0」の場合は、「0」を削除して詰めるので、ゼロサプレスを行う関数を定義。
  3. 小数点がある値の場合は、小数点の位置で文字列を分離。
  4. 計算結果が「1」より小さくなるまで値を「10000」で割り、該当する万進の単位を挿入する。
  5. 関数の返り値として、表記を変換した文字列を返す。
function ag2manshin(a){
  //数値に変換できなかった場合
  if(isNaN(Number(a))) return console.log('Error : Not a Number.');
  //1万未満の場合
  if(Number(a) < 10000) return a;

  //ゼロサプレスを行う関数
  function ag2zeroSuppress(n){
    let i = 0;
    while (String(n).charAt(i) === '0') i++;
    return String(n).slice(i);
  }

  let hiNum, lowNum, pointNum, manshinUnit, manshinUnitLen;

  manshinUnit = ['万','億','兆','京','垓','𥝱','穣','溝','澗','正','載','極','恒河沙','阿僧祇','那由他','不可思議','無量大数'];
  manshinUnitLen = manshinUnit.length;

  //小数点を含めている場合
  if(String(a).split('.').length > 1){
    pointNum = '.' + String(a).split('.')[1];
    a = String(a).split('.')[0];
  }else{
    pointNum = '';
  }

  hiNum = a;
  lowNum = '';

  for(let i = 0, j = 0, k = (a / 10000); j < manshinUnitLen &&  k >= 1; i++, j++, k /= 10000){
    //下4桁をチェックして処理
    //4桁とも0の場合は万進の単位を削除
    if(i > 0 && !ag2zeroSuppress(String(hiNum).slice(-4))) lowNum = String(lowNum).slice(1);
    //1文字目に万進の単位、後ろに処理済みの下4桁を付けて保持
    lowNum = manshinUnit[i] + ag2zeroSuppress(String(hiNum).slice(-4)) + lowNum;

    //下4桁を削除して保持
    hiNum = String(hiNum).slice(0,-4);
  }

  //変換した表記の文字列を返す
  return hiNum + lowNum + pointNum;
}

 

関数の実行

上述で作成した関数を任意の場所で実行する。

JavaScriptでは、「Number.MAX_SAFE_INTEGER」である「9007199254740991」を超える数値だと誤差が発生してしまうので、結果の精度を担保したい場合は数値ではなく必ず文字列の状態で引数に指定する。

※ JavaScriptの数値には「IEEE 754」の規格が採用されているため、「9007199254740991」より大きな数値は勝手に丸まめられるので、下数桁の精度が保証されない。

let thisNum = ag2manshin('1000010000000');
console.log(thisNum);
//出力されるコンソールの内容
//1兆1000万

let thisNum = ag2manshin('1001000100010');
console.log(thisNum);
//出力されるコンソールの内容
//1兆10億10万10

let thisNum = ag2manshin('123456789');
console.log(thisNum);
//出力されるコンソールの内容
//1億2345万6789

let thisNum = ag2manshin('123456789123456789');
console.log(thisNum);
//出力されるコンソールの内容
//12京3456兆7891億2345万6789

//JavaScriptでは15桁を超えた数値は勝手に丸まる
let thisNum = ag2manshin(123456789123456789);
console.log(thisNum);
//出力されるコンソールの内容
//12京3456兆7891億2345万6780

 

 

PHPで変換処理する場合

PHPで、数値に万進の単位を挿入した文字列に変換する関数を作成して、引数に数値を指定して実行する方法。

 

変換する関数を作成

引数で受け取った値を、桁数に応じて万進の単位を挿入した文字列に変換して返す関数を作成する。

  1. 引数で渡された値が数値として扱えるかチェック。(数値に変換できない文字列の場合はエラー処理。)
  2. 小数点がある値の場合は、小数点の位置で文字列を分離。
  3. 計算結果が「1」より小さくなるまで値を「10000」で割り続けて処理を実行。
  4. 値から下4桁を取り出して、1文字目に万進の単位を付与する。(残りの値が「10000」で割れる場合は再度同じ処理。)
  5. 関数の返り値として、表記を変換した文字列を返す。
function ag2manshin($num){
  //値が数値か確認
  if(!is_numeric($num)) return 'Error : Not a Number.';
  //1万未満の場合
  if($num < 10000) return $num;

  $manshin_unit = ['万','億','兆','京','垓','𥝱','穣','溝','澗','正','載','極','恒河沙','阿僧祇','那由他','不可思議','無量大数'];
  $manshin_unit_num = count($manshin_unit);

  //小数点を含めている場合
  if(preg_match('/[.]/', $num)){
    $point_num = '.'.explode('.', $num)[1];
    $num = explode('.', $num)[0];
  }else{
    $point_num = '';
  }

  $hi_num = $num;
  $low_num = '';

  for($i = 0, $j = 0, $k = ($num / 10000); $j < $manshin_unit_num && $k >= 1; $i++, $j++, $k /= 10000){
    //下4桁をチェックして処理
    //4桁とも0の場合は万進の単位を削除
    if($i > 0 && !ltrim((mb_substr($hi_num, -4)), 0)) $low_num = mb_substr($low_num, 1);
    //1文字目に万進の単位、後ろに処理済みの下4桁を付けて保持
    $low_num = $manshin_unit[$i].ltrim((mb_substr($hi_num, -4)), 0).$low_num;

    //下4桁を削除して保持
    $hi_num = mb_substr($hi_num, 0, -4);
  }

  //変換した表記の文字列を返す
  return $hi_num.$low_num.$point_num;
}

 

関数の実行

上述で作成した関数を任意の場所で実行して出力する。

echo ag2manshin(1001000100010);
//出録結果
//1兆10億10万10

echo ag2manshin(123456789);
//出録結果
//1億2345万6789

echo ag2manshin(123456789123456789);
//出録結果
//12京3456兆7891億2345万6789

 

 

この記事のURL

https://memo.ag2works.tokyo/post-4722/

Copyコピー
この記事のタイトル

桁の大きな数値を万進の表記に変換して表示。 | memo メモ [AG2WORKS]

Copyコピー
この記事のリンクタグ

<a href="https://memo.ag2works.tokyo/post-4722/" target="_blank" rel="noopener">桁の大きな数値を万進の表記に変換して表示。 | memo メモ [AG2WORKS]</a>

Copyコピー
※ フィールドをクリックでコピーするテキストの編集ができます。

この記事へのコメント

コメントの書き込みはまだありません。

  • コメント内のタグはエスケープ処理され、文字列として出力されます。
  • セキュリティーのため、投稿者のIPアドレスは取得されます。
  • 管理者が内容を不適切と判断したコメントは削除されます。
  • このフォームにはスパム対策として、Googleの提供するreCAPTCHAシステムが導入されています。
    (Google Privacy Policy and Terms of Service.)