以前、いっしょに仕事をしていた技術者から聞いて驚いたことがあります。Javaでは、ビット操作を行うときにはいったん文字列を介して行うというのです。私はJava界隈の事情には明るくないのですが、本当にそうなんでしょうか?
その技術者いわく、いったん文字列に変換してから操作して、再び整数に戻す方が「わかりやすい」といいます。また、そのようにしないと現場のリーダーから「𠮟られる」ともいうのです。
私には未知の感覚でしたので、実際に文字列を介したビット操作をいうのを試してみました。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
import java.lang.*; public final class Bitwise { // ビットごとの論理積 public static int and(int lhs, int rhs) { String s1 = String.format("%32s", Integer.toBinaryString(lhs)); String s2 = String.format("%32s", Integer.toBinaryString(rhs)); String r = ""; for (int i = 0; i < 32; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 == '1' && c2 == '1') r += '1'; else r += '0'; } return Integer.parseInt(r, 2); } // ビットごとの論理和 public static int or(int lhs, int rhs) { String s1 = String.format("%32s", Integer.toBinaryString(lhs)); String s2 = String.format("%32s", Integer.toBinaryString(rhs)); String r = ""; for (int i = 0; i < 32; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 == '1' || c2 == '1') r += '1'; else r += '0'; } return Integer.parseInt(r, 2); } // ビットごとの排他的論理和 public static int xor(int lhs, int rhs) { String s1 = String.format("%32s", Integer.toBinaryString(lhs)); String s2 = String.format("%32s", Integer.toBinaryString(rhs)); String r = ""; for (int i = 0; i < 32; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 != c2) r += '1'; else r += '0'; } return Integer.parseInt(r, 2); } // 左シフト public static int shiftLeft(int lhs, int rhs) { String r = Integer.toBinaryString(lhs); for (int i = 0; i < rhs; i++) { r += '0'; } return Integer.parseInt(r, 2); } // 右論理シフト public static int shiftRight(int lhs, int rhs) { String r = Integer.toBinaryString(lhs); if (rhs < r.length()) { r = r.substring(0, r.length() - rhs); return Integer.parseInt(r, 2); } return 0; } } |
正直、書いている途中でバカバカしくなってきました。本当は算術右シフトも作ろうと思っていたのですが、やる気がなくなったので作っていません。
なぜ、1~2文字の演算子を書くだけで済むものを、こんな面倒なコードで置き換えないといけないのかまったくの謎です。確かに、私はJavaはへたくそですから、もっと効率のよいコードを書けるかもしれません。しかし、どんなに頑張ってチューニングできたとしても、演算子を素直に使う方法にかなうはずがありませんよね。
こんな馬鹿なことをしないといけないのは、その技術者がこれまでたまたま関わってきた職場特有のことなのでしょうか? それとも、Javaを使った開発現場全般にいえることなのでしょうか? もしかして、いわゆる「業務系」の開発現場はこんな感じなのでしょうか?
これは私の想像ですが、もしかするとJava以外のプログラミング言語、たとえば、JavaScriptやPython、Ruby、PHPなんかでも同じようなことがあるのでしょうか?
ちなみにその技術者は、ビット演算やシフト演算を使ったコードのことを「C」と呼んでいました。