Java 任意の位置に小数点を追加してみる

皆さ~ん、数字に小数点を追加したいと思ったことありませんか?ワシもじゃ、ワシもじゃ、みんな!!

atarimae.biz

⇧  上記サイト様の説明にあるような、無限に続く小数点とかは対象外で。

 

そして、常駐先の同僚の方に、教えていただき、

techplay.jp

⇧  イベントに参加してきました。

開催地が、外苑前駅だったのですが、渋谷の乗り換えのところで銀座線の場所が見つからずで迷子になり、30分遅れでの参加になってしまいましたが、事前に遅れる旨の連絡をしたところ、大丈夫ですよ、と仰っていただけました。

無事到着しまして、話を聞きましたところ、時代は、JavaScriptみたいな感じらしいっす。でも、1つの言語を深く勉強したほうが、他の言語を勉強するときの学習コストが下がると仰っていました。

SRE(Site Reliability Engineering)という道もこれからは求められるだろうと。

codezine.jp

 

あと、アメリカでは、化物級にできるエンジニアは確かにいるけど、Googleとかの技術者でも、一般の技術者とどんぐりの背比べ的な様子らしいですとも仰っていましたかね。

技術者分布図イメージ

f:id:ts0818:20190126223610p:plain

⇧  イメージ的には、一部のスーパーエンジニアが業界を引っ張っているそうです。Googleなんかにおるエンジニアでも、一般のエンジニアと変わらん場合も多いそうな...

ただ、お話をしていただいた 河村 綾祐さんは実際にアメリカなどでもエンジニアとして働いた感覚として、

シリコンバレーがなんぼのもんじゃい!

的な感覚を持ったと、日本は技術力で負けてないと。ご飯も美味しいし、ビバ!Japan!

あと、技術力は、自分で頑張って身につけるしか無いとの厳しいご意見も...個人的にはOJTとか体験してみたいんですが...

 

 

というわけで、まったくやる気が出なくなったところで、今回もJavaで。レッツ~トライ。

 

小数点の表現、ピリオドだったりカンマだったり...半角スペース?

なんていうか、 ハッキリしないけど、Wikipediaさんによりますと、

小数点(しょうすうてん、en:Decimal separatorまたはdecimal marker)とは、実数を数字列で表記したときの整数部と小数部との境を表す記号であり、アラビア数字の場合、「ピリオド」(:dot)または「コンマ」(comma)が用いられる。現代の日本では、ピリオドを用いることがほとんどである。

小数点 - Wikipedia

⇧  と、日本だと、ほぼ、ピリオドらしい。

日本語では単に「小数」ということが多い。英語では、decimal point、decimal separator,decimal marker などと呼ばれる。point はまさしく「点」であり、小数点としてピリオドを用いる国・文化では問題がない。しかし、小数点としてコンマを用いる国ではそぐわないので、decimal separator,decimal marker が好まれる。

小数点 - Wikipedia

⇧  文化による相違とかは、混乱のもとなのでやめて欲しい。

小数点として点(dot on the line)を用いるか、コンマ(comma on the line)を用いるかは、国、地域、文化によってまちまちである。ごく大まかには、イギリス、米国、日本、中国、インドでは「点」を用い、フランス、ドイツ、イタリア、スペイン、ロシアでは「コンマ」を用いる。以下では、国際単位系(SI)での呼び方にならって、「点」を用いる方式を「イギリス式(British practice)」、「コンマ」を用いる方式を「フランス式(French practice)」と呼称する。

小数点 - Wikipedia

⇧  文化による相違とかは、混乱のもとなのでやめて欲しい。

国際単位系(SI)では小数点について、イギリス式でもフランス式でも、どちらでもよいと規定している。ただし、桁の区切りについては、整数部でも小数部でも、半角のスペース(thin space)に限るとしていて、ピリオドやコンマの使用を禁じている。

小数点 - Wikipedia

⇧  え?どういうこと?

⇧  ん?

⇧  ん? 

小数点表記の、国家や言語による差異は重大な誤解が危惧されるので、国際標準を策定するISOIECなどは、英語を含む全ての言語表記でフランス式を統一的に用いると定めている。

小数点 - Wikipedia

⇧  ん? 

⇧  ということで、結局、統一が取れていないらしい...烏合の衆ここに極まれり......

 

とりあえず、小数点1つを追加の実装で

金額とかだと、『1,980,000』みたいにカンマが複数入りますが、今回は、あくまで数学的な小数点という意味合いで、『1.980000』みたいなことにトライ。

金額のようなカンマ編集については、

blog.java-reference.com

⇧  上記サイト様が詳しいです。

 

というわけで、Eclipseで、Javaプロジェクトを適当に作成。

f:id:ts0818:20190126214614p:plain

ソースはこんな感じにしてみました。
 

package main;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class TestConmma {

  public static void main(String[] args) {
    // TODO 自動生成されたメソッド・スタブ
    String numberStr = "0001230";  // 数値文字列
    char[] numberCharArr = null;  // 数値文字列を文字配列にする用
    String decimalPointNumberStr = null;  // 小数点追加後の数値文字列
    int decimalPosition = 1;  // 小数点追加位置
    if (numberStr != null) {
      numberCharArr = numberStr.toCharArray();
      Map<Integer, String> map = zeroStartSuppressAndEndPaddingNumber(numberStr, numberCharArr);
      decimalPointNumberStr = makeDecimalPointNumber(map, decimalPosition);
    }
    System.out.println(decimalPointNumberStr);
  }

  /**
   * 小数点を含む数値文字列を生成
   * @param targetNumber
   * @param decimalPosition
   * @return 小数点を含む数値文字列を返す
   */
  public static String makeDecimalPointNumber(Map<Integer, String> targetNumber, int decimalPosition) {
    StringBuffer sb = new StringBuffer();
    String decimalPointNumber = null;
    try {
      if (decimalPosition == 0) {
        throw new IllegalArgumentException("小数点位置が0はNG。makeDecimalPointNumberメソッドの引数を見直してください。");
      }
      for (Entry<Integer, String> entry: targetNumber.entrySet()) {
        if (entry.getValue().length() < decimalPosition || decimalPosition < 0) {
          throw new IllegalArgumentException("小数点位置が許容範囲を超えているのはNG。makeDecimalPointNumberメソッドの引数を見直してください。");
        }
        decimalPointNumber = entry.getValue();
        sb.append(decimalPointNumber.substring(0, decimalPosition));
        sb.append(".");
        sb.append(decimalPointNumber.substring(decimalPosition));
      }

    } catch (IllegalArgumentException e) {
      // TODO 自動生成された catch ブロック
      // e.printStackTrace();
      System.out.println(e.getMessage());
      System.exit(1);//プログラムを終了する。
    }

    return sb.toString();
  }

  /**
   * 先頭を0サプレスして、後ろを0パディングする
   * @param targetStr
   * @param numberCharArr
   * @return 先頭を0サプレスして、後ろを0パディングした結果
   */
  public static Map<Integer, String> zeroStartSuppressAndEndPaddingNumber(String targetStr, char[] numberCharArr) {

    Map<Integer, String> map = new HashMap<>();
    int addZeroSuppressCount = 0;
    // ゼロサプレス
    for (int index = 0; index < numberCharArr.length;index++) {
      if('0' != numberCharArr[index]) {
        // ゼロサプレス後の数値文字列
        targetStr = targetStr.substring(addZeroSuppressCount);
        break;
      }
      addZeroSuppressCount++;
    }
    // ゼロパディングした文字列
    targetStr = zeroEndPaddingNumber(targetStr, addZeroSuppressCount);
    map.put(addZeroSuppressCount, targetStr);
    return map;
  }

  /**
   *  後ろを0パディングする
   * @param targetStr
   * @param addZeroPaddingCount
   * @return 0パディングした数値文字列
   */
  public static String zeroEndPaddingNumber(String targetStr, int addZeroPaddingCount) {
    // ゼロパディング
    for (int index = 0; index < addZeroPaddingCount; index++) {
      targetStr += "0";
    }
    return targetStr;
  }

}

んで、実行してみる。

f:id:ts0818:20190126214944p:plain

f:id:ts0818:20190126215039p:plain

⇧  『0001230』を先頭からゼロサプレスし、1つ目の数字の後に小数点を追加してます。後ろにゼロパディングの数は、小数点の分を考慮する場合は、-1減らす必要がありますかね。イケてないプログラムではありますが...

まぁ、一般的に、受け取る桁数、加工後の桁数をどうするかは事前に決められていると思われるので、その時々で調整して行く感じで。もしくはプログラムを汎用的な記述にするなど。

後者の、汎用的なプログラムにするのが本当は望ましですが...技術力が欲しいっす...

 

今回は、前からゼロサプレスして、後ろにゼロパディングしてますが、後ろゼロサプレス、前ゼロパディングとかもあると思うし、ゼロでなく、半角スペースとかでサプレスしたりパディングしたりもあると思うので、難しいものですね。

 

ゼロサプレスとゼロパディングについては、

necro.jp

⇧  上記サイト様が詳しいです。

 

というわけで、今回はこのへんで。