Java char型同士で引き算とかできるそうな

文字から文字を引いたら?どうなるかというと、数値になるという不思議、どうもボクです。

Javaのchar型同士を引き算すると、まぁ、何ということでしょう!そうです、int型 の結果を得ることができるらしいですね、いや~意味が分からんのですけどね。

というわけで、今回も、Javaです。

 

char型同士の減算で、int型

いや~、もう摩訶不思議すぎて「絶句(杜甫)」な気分で、

(こう)(みどり)にして鳥(とり)逾々(いよいよ)(しろ)
(やま)(あお)くして花(はな)(も)えんと欲(ほっ)
今春
(こんしゅん)看々(みすみす)(また)(す)
(いず)れの日(ひ)か是(こ)れ帰年(きねん)ならん

絶句

と思わず、詠じてしまいそうですかね。

teratail.com

⇧ 上記サイト様によりますと、char型の内部仕様により、char型同士の引き算は、int型になるらしい、なんじゃそりゃ~。

 

www.sasukepg.jp

⇧  上記サイト様によりますと、文字コードと、char型の内部仕様の数値はまったく別物ってことになるってことですかね...

 

文字コードについては、

equj65.net

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

アルファベットの大文字「A」は、

ja.wikipedia.org

⇧  Unicode は、16進数で「0x41」、10進数だと「65」。

ja.wikipedia.org

⇧  ASCII も、16進数で「0x41」、10進数だと「65」。 

そんじゃあ、UnicodeとASCII って何が違うのよ?

code.i-harness.com

⇧  もともと、ASCII が先に作られたらしいんだけど、表現できる文字が少ないってことで、Unicode が作られたそうです。

Unicode は世界で使われる全ての文字を共通の文字集合にて利用できるようにしようという考えで作られ、UnixWindowsmacOSPlan 9Javaなどで利用されている。現代の文字だけでなく古代の文字や歴史的な文字、数学記号、絵文字なども含む

Unicode - Wikipedia

⇧  Java 以外でも使われていると思うけど...使われてないのかな?「Plan 9」は「UTF-8」の元になったものらしい。

Unicodeでは文字符号化方式も標準化したため、従来見られたShift JISEUC-JPとの間の混乱のようなものは回避されている。

Unicode - Wikipedia

⇧  文字化けのことを言っているんでしょうね。 

Unicode以前の文字コードとの相互運用性もある程度考慮されており、歴史上・実用上の識別が求められる場合には互換領域がとられ、元のコード→Unicode→元のコードというような変換(ラウンドトリップ変換)において、元通りに戻るよう配慮されている文字もある。

Unicode - Wikipedia

⇧  文字化けのことを言っているんでしょうね。 

しかし、正規のJIS X 0208の範囲内であればトラブルは少ないが、複数の文字集合が混在したり、Shift JISの実態であるCP932EUC-JPの亜種であるCP51932とeucJP-MSなど、対応が違うために文字化けを起こすことがある。

Unicode - Wikipedia

⇧  結局、文字化けは起こるんだ...混乱は回避できていないじゃないですか...

 

すみません、脱線したのですが、

アルファベットの大文字は、文字コードだと「65(10進数表記)」で表せるのだと。

対して、Javaのchar型では、「A」、「a」はともに「10(10進数表記)」になっているんですな、どんだけ~!って叫びたくなるぐらい意味不明ですな。

public static int getNumericValue(char ch)
指定されたUnicode文字が表すint値を返します。たとえば、文字'\u216C' (ローマ数字の50)は、値50のintを返します。

文字A - Zの大文字('\u0041' - '\u005A')、小文字('\u0061' - '\u007A')、全角バリアント('\uFF21' - '\uFF3A'および'\uFF41' - '\uFF5A')の各形式は、10 - 35の数値を持ちます。これはUnicode仕様とは無関係であり、Unicode仕様ではこれらのchar値に数値は割り当てられません。

文字が数値を持たない場合は、-1が返されます。文字の数値を負でない整数として表現できない場合(小数値など)は、-2が返されます。

注: このメソッドは、補助文字を処理できません。補助文字を含むすべてのUnicode文字をサポートするには、getNumericValue(int)メソッドを使用してください。

Character (Java Platform SE 8)

⇧  何故か、アルファベット(半角)の大文字、小文字、アルファベット(全角バリアント )の大文字、小文字は、なんか特殊な扱いらしく、10~35 の数値で扱われているという...謎すぎる、というか何かUnicode仕様とは別にしないといけない理由があったのかしら...。

それ以外は、Unicode文字コードと対応が取れているらしい。という認識で良いのだろうか...。

全角バリアントって何のこっちゃ?だけど、全角っていうことで良いかと。

www.fileformat.info

 

 

実際に、char型でのアルファベットって数値として見た場合はどうなるの?ってことで確認してみました。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class CoutingChar {

  public static void main(String[] args) throws IOException {
    // 標準入力を受け取る用のオブジェクト
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

    // アルファベットの数用リストを作成
    int[] counter = new int[26];
    char ch = 'a';

    char[] inputCharArr = null;
    String line = null;
    while ((line = (input.readLine())) != null) {
      // 入力値を取得
      inputCharArr = line.toCharArray();
      for (int i = 0; i < inputCharArr.length; i++) {
        if ('A' <= inputCharArr[i] && inputCharArr[i] <= 'z') {

          if (Character.isUpperCase(inputCharArr[i])) {
            inputCharArr[i] = Character.toLowerCase(inputCharArr[i]);
          }
          // char型でのアルファベットの数値の確認
          System.out.println(inputCharArr[i] + "-" + 'a' +"="+ (inputCharArr[i] - 'a') + ":" + Character.getNumericValue(inputCharArr[i]) + "-" + Character.getNumericValue('a'));
          int num = inputCharArr[i] - 'a';
          counter[num]++;
        }

      }
      // 結果出力
      for (int i = 0; i < counter.length; i++) {
        System.out.println(ch++ + " : " + counter[i]);
      }
    }
  }
}

起動して、適当なアルファベットの文字列を入力。

f:id:ts0818:20190211134034p:plain

自動で終了しないので、f:id:ts0818:20190211134128p:plainで止めるのを忘れずに。

f:id:ts0818:20190211134105p:plain

確かに、アルファベットは、10~35 の数値が割当られてるっぽいですね、なんだろう、このモヤモヤ感は...。

文字の扱いはかなりカオスな感じですかね...

 

というわけで、今日もまたモヤモヤした状態のままなのですが、今回はこのへんで。