Serviceを読んで理解し、同意したものとみなします。スタック・オーバーフローはプログラマーとプログラミングに熱心な人のためのQ&Aサイトです。(~0b1010).to_s(2)は"-1011"になりました。Yahoo!知恵袋にはここで注意して頂きたいのが、負の数の管理方法です。一言で言うと、「その数にいくつ足すと0になるか」です。000000000000000000000000000000とあります。なにか計算によって0が並ぶような数値がビット反転の答えになると推測しました。10101になるので、理解できません。[~0b1010].pack('L').unpack('L')[0])がそれぞれ"1010""11111111111111111111111111110101"となって、名前のとおり反転していることがわかりました。(~0b1010).to_s(2)としてみたところ"-11""-1011"となったので、10進数で-112進数で-1011になることがわかりました。言える気がしてきました。すると分かるかと思います。0が並ぶ計算方法はわかりました。1->0)したものに等しくなるから、という事です。ビット反転」で検索してみると、より丁寧で正確な説明をしてくれている記事が見つかるかと思います。票2ご質問に記載された挙動をきちんと理解しようと思うと、整数を2進数で表す場合の2の補数表現について正しく理解しておく必要があります。^はビット演算ではなくべき乗を表すものとする)の値を表現できます。15コンピュータ上で負の整数を表すやり方にはいろいろあるのですが、最上位ビットが1の場合が負数を表すことにして次のように値を割り振るのを「2の補数表現」と言います。7初めてみると、何か不自然な並びに見えるかもしれませんが、(2進)1111に1を足すと(2進)10000になります。計算処理が固定長でしかできないことにして、桁あふれを無視すると結果は(2進)0000つまり0になります。いう表現方法を取っていることになります。【Rubyの場合】Rubyの場合は、無限多倍長整数が使えるので話がちょっとややこしくなるのですが、整数値の0b1010と言うのは正の数のはずですから最上位ビットは内部的には0でないといけません。4ビットの2の補数表現で表せる範囲を超えているのです。Rubyの整数処理では必要なビット数をどんどん補ってくれるので、概念的に言うと0b1010は(2進)...0000000000001010と言うような感じで、上位ビットに延々と0が連なる整数を表していると思わないといけません。従って、それを反転した~0b1010は、こんな数を表していると言うことになります。(2進)...1111111111110101これは最上位ビット(?)が1ですから、負の数、値としては(2進)...0000000000001010(=10)を足すと...1111111111111111(=-1)になりますから、2の補数的には(10進)-11を表している、と考えられるのです。(10進)11を2進法で表すと1011で、値が負なので、to_s(2)が作り出す「符号+絶対値表現」では-1011なんて表記になります。(「概念的には」と言うことで、内部的には「符号を表す1ビットまで含めて32ビットに収まるときには32ビットで表す」なんてことをしています。)と言うわけでコメントに書かれていることをまとめ直しただけで、「どうして~0b1010は10進数で-11になるのか?」を説明したつもりなのですが、お分かりいただけましたでしょうか。何か分かりにくい部分があればコメントして下さい。|0まずは整数がどのようなビット列として考えられているのかを理解する必要があります。ビット列とは何かです。始めに、Rubyのビット演算の基になったCでの場合を考えます。Cのintは環境依存の範囲の符号付き整数を表します。4バイト(1バイトは8ビット)、つまり、32ビットになっています(範囲やバイト数、1バイトあたりのビット数は環境依存であり、これにあてはまらない環境も存在することに注意してください)。実際の値はメモリ上のビットとして存在しており、0と1の列として表現されます。数字の42を表現した場合は次のようになります。(42)メモリはバイト毎に管理するため、8ビット毎にまとめた形で記録されています(わかりやすいように8区切りにしたのはそのためです)。アーキテクチャによって、上位バイトから収める場合(ビッグエンディアン)と下位バイトから収める場合(リトルエンディアン)の二つがあります。これはメモリ上の配置の問題であり、ビット列としてはまとめて一つの列として扱われるため、どちらであっても関係ありません。正の数は上のように2進数表記と同じになります。0は全て0になるだけですので、こちらも問題ありません。問題となるのは負の数の表現方法です。ビット列における負の数の表現には主に二つの方法があります。一つが1の補数、もう一つが2の補数です。1の補数は単純に全てのビットを反転することで表現します。-42は次のようになります。(-42の1の補数表現)しかし、ほとんどの環境では2の補数を採用しています(1の補数を採用している環境が現在も存在するかは不明ですが、Cの仕様上は1の補数もあり得ます)。2の補数は表現可能なビット列より1桁だけ大きい数からその数の絶対値を引いた数のビット列が負の数になります。(-42の2の補数表現)ここまでは整数値に範囲が存在する言語での話です。Rubyの整数値であるIntegerは(メモリが許す限り)無限の範囲を持っており、どこまでも大きくなります。そのため、ビット列というものも無限の大きさで考える必要があります。Rubyのビット列の考えはCと同じです。負の数についても2の補数表現を使用します。無限の大きさになるため、無限に大きいビット列であると考える必要があります。(42)...の部分はその後の部分の繰り返しが永遠に存在する、つまり、0または1が無限にあると考えてください。2の補数を考えるときは表現可能なビット列より1桁大きいと言うことでしたが、今回は無限の大きさです。そこで、無限遠の先に1があると想定して考えます。(-42)数学的には間違っていますが、イメージとしては上のような形です。無限と言うよりも「十分に大きい」という表現のほうが数学的には正確になると思います。ここからビット反転を考えてみましょう。1の補数であれば負の数にするだけでしたが、2の補数ですのでそうはいきません。(~42)この数がいくらになるかですが、符号を逆転させれば絶対値がわかります。符号を逆転する方法は負の数にした方法と同じです。(43)つまり、0b101011の負の数、-43になります。2進数で表現すると"-101011"となるでしょうが、ビット列としては42を反転させた物になると言うことです。説明しましたが、2の補数表現におけるビット反転は「正負を反転させて-1した数」と同じになります。上では42で考えてみましたが、10(0b1010)の場合はどうなるかは自分で考えてみてください。2.3.xまではIntegerは実装上FixnumとBignumの二つに分かれていました。これは実装上の話であり、言語上は区別なく使用できました。実装上は依然として二つ存在しますが)。30桁のビット列で考えるという解説を見ることがありますが、Fixnumの実装での話であり、全てを説明することはできません。言語仕様上はBignumのような無限の大きさの範囲で考える必要があります。|回答スタック・オーバーフローに参加してくれて、ありがとうございます!質問の回答を共有してください。回答を説明し、自分の検討結果も共有してください。意見を述べること(意見を述べるなら、参照リソース、自分の経験で意見をサポートしてください)さらにサポートが必要な場合このヘルプを参考してください。“回答を投稿”をクリックすることで利用規約、プライバシーポリシー、及びクッキーポリシーに同意したものとみなされます。タグが付いた他の質問を参照するか、自分で質問をする。使える環境にするためには?0Rubyの連続するif文2rubyのFileクラス拡張について0投稿ページが複数ある場合のデータベースの設計について聞きたいです。質問のフィードこのRSSフィードを購読するには、このURLをコピーしてRSSリーダーに貼り付けてください。