文字から文字を引いたら?どうなるかというと、数値になるという不思議、どうもボクです。
Javaのchar型同士を引き算すると、まぁ、何ということでしょう!そうです、int型 の結果を得ることができるらしいですね、いや~意味が分からんのですけどね。
というわけで、今回も、Javaです。
char型同士の減算で、int型
いや~、もう摩訶不思議すぎて「絶句(杜甫)」な気分で、
江(こう)碧(みどり)にして鳥(とり)逾々(いよいよ)白(しろ)く
山(やま)青(あお)くして花(はな)然(も)えんと欲(ほっ)す
今春(こんしゅん)看々(みすみす)又(また)過(す)ぐ
何(いず)れの日(ひ)か是(こ)れ帰年(きねん)ならん
と思わず、詠じてしまいそうですかね。
⇧ 上記サイト様によりますと、char型の内部仕様により、char型同士の引き算は、int型になるらしい、なんじゃそりゃ~。
⇧ 上記サイト様によりますと、文字コードと、char型の内部仕様の数値はまったく別物ってことになるってことですかね...
文字コードについては、
⇧ 上記サイト様が詳しいです。
アルファベットの大文字「A」は、
⇧ Unicode は、16進数で「0x41」、10進数だと「65」。
⇧ ASCII も、16進数で「0x41」、10進数だと「65」。
そんじゃあ、UnicodeとASCII って何が違うのよ?
⇧ もともと、ASCII が先に作られたらしいんだけど、表現できる文字が少ないってことで、Unicode が作られたそうです。
Unicode は世界で使われる全ての文字を共通の文字集合にて利用できるようにしようという考えで作られ、Unix、Windows、macOS、Plan 9、Javaなどで利用されている。現代の文字だけでなく古代の文字や歴史的な文字、数学記号、絵文字なども含む。
⇧ Java 以外でも使われていると思うけど...使われてないのかな?「Plan 9」は「UTF-8」の元になったものらしい。
⇧ 文字化けのことを言っているんでしょうね。
Unicode以前の文字コードとの相互運用性もある程度考慮されており、歴史上・実用上の識別が求められる場合には互換領域がとられ、元のコード→Unicode→元のコードというような変換(ラウンドトリップ変換)において、元通りに戻るよう配慮されている文字もある。
⇧ 文字化けのことを言っているんでしょうね。
しかし、正規のJIS X 0208の範囲内であればトラブルは少ないが、複数の文字集合が混在したり、Shift JISの実態であるCP932やEUC-JPの亜種であるCP51932とeucJP-MSなど、対応が違うために文字化けを起こすことがある。
⇧ 結局、文字化けは起こるんだ...混乱は回避できていないじゃないですか...
すみません、脱線したのですが、
アルファベットの大文字は、文字コードだと「65(10進数表記)」で表せるのだと。
対して、Javaのchar型では、「A」、「a」はともに「10(10進数表記)」になっているんですな、どんだけ~!って叫びたくなるぐらい意味不明ですな。
public static int getNumericValue(char ch)
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)
メソッドを使用してください。
⇧ 何故か、アルファベット(半角)の大文字、小文字、アルファベット(全角バリアント )の大文字、小文字は、なんか特殊な扱いらしく、10~35 の数値で扱われているという...謎すぎる、というか何かUnicode仕様とは別にしないといけない理由があったのかしら...。
それ以外は、Unicodeの文字コードと対応が取れているらしい。という認識で良いのだろうか...。
全角バリアントって何のこっちゃ?だけど、全角っていうことで良いかと。
実際に、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]); } } } }
起動して、適当なアルファベットの文字列を入力。
自動で終了しないので、で止めるのを忘れずに。
確かに、アルファベットは、10~35 の数値が割当られてるっぽいですね、なんだろう、このモヤモヤ感は...。
文字の扱いはかなりカオスな感じですかね...
というわけで、今日もまたモヤモヤした状態のままなのですが、今回はこのへんで。