irbにおける"~(チルダ)"によるビット反転

```
mypc:~ current$ irb
irb(main):001:0> "irb完全に理解した".length
=> 10
irb(main):002:0> ~
irb(main):003:0* "irb完全に理解した".length
=> -11
irb(main):004:0> 
```

#はじめに
ことの発端は上記。何をしているかを簡単に説明すると

```
1行目$ irb実行
2行目> "irb完全に理解した"という文字列に対しlengthメソッドを実行
=> "irb完全に理解した"の文字数である10が返り値として出力
4行目> ~を入力
5行目* "irb完全に理解した"という文字列に対しlengthメソッドを実行
=> -11が返り値として出力される
```
なぜ ~ を入力したのかはこの際問題ではない(実際ただのタイプミスだ)。
ここで生じた疑問は以下の3つである。
**疑問1**, ~ とはなんなのか？
**疑問2**, プロンプトの末尾が * になるのはなぜか？
**疑問3**, なぜ1,2の状態において返り値が変わるのか？
###疑問1について
**~**(チルダ)**はIntagerクラスのオブジェクト**(整数)**に対してビット単位で演算を行うための演算子**(ビット演算子)**の一種である。**
その役割は**ビット反転**であり、**~a**(a = Integer)と記述することで「aを2進数に変換した際の各桁の数字(0或いは1)をそれぞれ入れ替える(0ならば1に, 1ならば0に)」というもの。
例えば、10進数における25は2進数では11001と表現されるが、それを~(チルダ)でビット反転させると00110(10進数における6)となる。
###疑問2について
プロンプトの末尾が * になっているのは、**irbが「コードが完結していない」と判断しているから**である。例えば

```
mypc:~ current$ irb
irb(main):001:0> hoge = "ホゲ"
=> "ホゲ"
irb(main):002:0> hoge =
irb(main):003:0* "ホゲ"
=> "ホゲ"
```
上記2~3行目の処理と4~6行目の処理は全く同一のものであると言える。
冒頭の5行目も、演算子である ~ を記述しただけの状態で改行したため、
irb側が「まだコードは完結しておらず、次の行には ~ によってビット反転される何かしらの値が入力されるはずだ」と認識したからであると思われる。

###疑問3について
疑問1,2の解答を踏まえ、もう一度冒頭のコードを確認する

```
mypc:~ current$ irb
irb(main):001:0> "irb完全に理解した".length
=> 10
irb(main):002:0> ~
irb(main):003:0* "irb完全に理解した".length
=> -11
irb(main):004:0> 
```
10進数の10を2進数に変換すると1010。
これに ~ をあてがうと、0101となる。
0101を10進数に変換すると、5となる。
この結果、返り値は5に––––––––––––––––––––––––––<br><br><br>
あれ？<br>
#新たな疑問 ~ちゃぶ台返し~
　　　　　　ありえない事態が起こったなら
　　　　　　　　疑うべきは２つだけだ

　　　　　　　前提条件が間違っているか
　　　　それともあんたの頭がいかれちまったか

　　　　　　　　　　　　　　　　　　　　〜狡噛慎也〜

そもそもの前提として私の頭はいかれていない。
これすら間違っているなら、最早この記事は出来損ないのドグラ・マグラである。
なので残る二つの前提条件、即ち疑問1,2の解答を疑うしかない。
疑うしかない。が、ともかくもまずは、情報を改めて整理しようと思う。
##~(チルダ)について
~(チルダ)について、改めて調べ直した。
Google師父に「ビット演算子 ~ チルダ」と入力し検索をかける。
すると[C#におけるチルダについて質問しているページ](https://www.it-swarm.dev/ja/c%23/%E5%BC%8F%E3%81%AE%E4%B8%AD%E3%81%A7%E3%83%81%E3%83%AB%E3%83%80%E3%81%AF%E3%81%A9%E3%81%86%E3%81%84%E3%81%86%E6%84%8F%E5%91%B3%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F/941708746/)がヒットした。他言語に関するページではあるが、共通する部分もあるだろう。

曰く、「**これは、ビットごとの否定とも呼ばれる ビットごとの補数 演算子です。**」とのこと。
ビットごとの否定...。これは疑問1でも言及した「ビット反転」と同義と捉えて問題ないだろう。
気になるのは**ビットごとの補数**である。[ご丁寧にリンクが貼られている](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#bitwise-complement-operator-)のでそちらを見に行く。

**"The ~ operator produces a bitwise complement of its operand by reversing each bit:"
「~オペレータは、各ビットを反転させることによって、そのオペランドのビット単位の補数を生成します。」**※Google翻訳
未履修言語の話なのであまり適当なことは言えないが、**ニュアンスは概ね同じ**のように思える。
しかしまた登場した。補数。...補数。補数???補数ってなんだったっけか。
とにかく、「~aとすることでaの補数を生成する」ということらしいが...
##補数について
いきなり数学の授業である。[Wikipedia](https://ja.wikipedia.org/wiki/%E8%A3%9C%E6%95%B0)を見れば全部書いてあるが、

「足すことによって桁上がりする数」
というのが補数の定義らしい。
例えば10進法における45に対する10の補数は55であり、
2進法における1101101に対する2の補数は10010である。

##~aをaに対する補数と仮定する
仮定の上で、再三にはなるが冒頭のコードを確認しよう

```
mypc:~ current$ irb
irb(main):001:0> "irb完全に理解した".length
=> 10
irb(main):002:0> ~
irb(main):003:0* "irb完全に理解した".length
=> -11
irb(main):004:0> 
```
10進数10を2進数に変換すると1010
10進数-11を2進数に変換すると11111111111111111111111111110101
...下4桁、明らかに怪しい。
が、とりあえずいくつか組み合わせを試して検証してみる。
<img width="563" alt="スクリーンショット 2020-07-06 7.48.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563175/093b5990-3d93-8adf-d9c0-b5316647d23c.png">
1がいっぱいである。そしてどうやら
10進数において、入力値(~は除く)+出力値=全て-1に
2進数において、入力値(~は除く)+出力値=全て11111111111111111111111111111111
になるらしいということがわかった。
#ひとまず結論
つまり、irbにおいて~(チルダ)は、11111111111111111111111111111111を基数とした上で
入力された値を2進数変換した値に対する11111111111111111111111111111111の補数を返り値として出力していたのである。
#11111111111111111111111111111111ってどこからきた？
状況は理解した。が原因がわからない。
**11111111111111111111111111111111**
32桁に1が収まっている。32...?
32ビットとか？関係ある？