下記リンク先で、桁を合わせるため、(r << 8)を(256 + r << 8)へ変更しているのですが、
・256を足すと、どうして2進数『1000000000000000000000000』を足したことになるのでしょうか?
2進数で表すところの『1000000000000000000000000』、10進数で『16777216』、16進数で『1000000』を足すことによって一時的に桁を合わせ
javascript
1function toColorCode_1a(r,g,b){ 2 return (((256 + r << 8) + g << 8) + b).toString(16).replace(/^1/,'#'); 3}
・1バイトが256だから?
・11111111?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー
>・256を足すと、どうして2進数『1000000000000000000000000』を足したことになるのでしょうか?
256を足したから1000000000000000000000000を足したことになっているのではなく
この256はr<<8とg<<8の8bit左シフト2回によって0x100 が 0x1000000 になっています。
256 + r << 8 の部分で256(0x100)は0x10000になっていて(1回目の8bit左シフト)
次の「(その演算結果+g)<<8」によって最初の256だった物はさらに8bit左にシフトされるため
結果として最初の256(16進の0x100)は最終的に0x1000000になっているという事です。
投稿2016/05/02 06:36
総合スコア2160
0
桁落ちの問題
単純に考えれば赤を16ビットシフト、緑を8ビットシフトすればいいですが、それでは赤が 0
の場合に桁落ちが発生してしまいます。
JavaScript
1'use strict'; 2function toColorCode (r, g, b) { 3 return '#' + ((r << 16) + (g << 8) + b).toString(16); 4} 5 6console.log(toColorCode(255, 255, 255)); // "ffffff" 7console.log(toColorCode(0, 0, 128)); // "#80"
桁落ちの回避策
桁落ちを回避するために 0x000080
を 0x1000080
のように変換している(一つ上の桁に 1
を置く)のでしょう。
256 を加算すると9bit目に1を置く事になります。
10進数で例えるなら「9 + 100 = 109」で2桁目をゼロパディングしているようなものですね。
JavaScript
1var r = 15; 2console.log(r.toString(16)); // "f" 3console.log((256 + r).toString(16)); // "10f" 4console.log((0x100 + r).toString(16)); // "10f"
N進数
Nを基数とするN進数には各桁となる数字に明確な計算法があります。
10進数で例えるなら、148
は次のように分解する事が出来ます。
JavaScript
1console.log(Math.pow(10, 0) * 8); // 8 … 1桁目は 10^0*8 (10の0乗の8倍) 2console.log(Math.pow(10, 1) * 4); // 40 … 2桁目は 10^1*4 (10の1乗の4倍) 3console.log(Math.pow(10, 2 * 1)); // 100 … 3桁目は 10^2*1 (10の2乗の1倍) 4console.log(Math.pow(10, 2) * 1 + Math.pow(10, 1) * 4 + Math.pow(10, 0) * 8); // 148
同じ事を16進数で考えればこうなります。
JavaScript
1console.log((Math.pow(16, 2) * 1).toString(16)); // 100 … 3桁目は 16^2*1 (16の2乗の1倍) 2console.log((Math.pow(16, 2) * 1)); // 256 … 10進数なら 256
従って、256 を加算するという事は16進数でいうところの「0x100
(16進数表記)」を加算する事と同義です。
「0x100
(16進数表記)」は2進数に換算すると「0b100000000
(2進数表記)」になります。
「0b100000000
(2進数表記)」は9bit目に1がある数字です。
2進数についてはご自身で計算(検証)してみてください。
別解コード
私なら次のようにコードを書きます。
JavaScript
1'use strict'; 2function toColorCode (r, g, b) { 3 return '#' + (0x1000000 + (r << 16) + (g << 8) + b).toString(16).slice(1); 4} 5 6console.log(toColorCode(255, 255, 255)); // "ffffff" 7console.log(toColorCode(0, 0, 128)); // "#000080"
ゼロパディングについては文字列処理をしてもいいので他の方法もあるとは思います。
更新履歴
- 2016/05/02 11:24 256加算のロジックの説明追加
- 2016/05/02 11:59 256加算のロジックの説明が誤っていたので修正
- 2016/05/03 11:55 N進数の説明追加
Re: re97 さん
投稿2016/05/02 02:17
編集2016/05/03 02:55総合スコア18156
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/03 02:58
2016/05/04 02:34
0
演算子の優先順位を考慮してビットシフトよりも先に足し算が行われるので
(((256 + r << 8) + g << 8) + b)
の計算の順番は16進数で考えて以下の通りになると思います。(例えば、r=1,b=2,g=0x80とすると)
256+r==>0x100+0x01=0x101
(256+r)<<8==>0x101<<8=0x10100
((256+r)<<8)+g==>0x10100+0x02=0x10102
((256+r)<<8)+g<<8==>0x10102<<8=0x1010200
(((256+r)<<8)+g<<8)+b==>0x1010200+0x80=0x1010280
最上位ビットの'1'を#に置換して
"#010280"
になります。
投稿2016/05/01 03:45
総合スコア1430
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/02 01:26
2016/05/02 01:42
2016/05/02 18:30
2016/05/03 01:20
0
ビット演算とか2進数とか16進数とかあまり関係ありません。ただ単に桁数を合わせたいだけです。
10進数で考えてもいいです。
9999以下の数値がいろいろあったとします。
1
12
888
2345
これを4ケタ未満だった場合に4ケタになるように0を付けたい。そういう話です。つまり
0001
0012
0888
2345
にしたいと。
そのために1万を足して
10001
10012
10888
12345
にして、先頭の1をとれば目的に文字列になるよねという話です。
初心者の方には逆にわかりにくくなっているかもしれませんが、こちらの方がシンプルですよね。
あと念のため
(((256 + r << 8) + g << 8) + b)
は
256 << 16
r << 16
g << 8
b
の4つの値を足したのと同じです。もしかするとこっちが分からなかった?
ちなみに
(256 << 16).toString(16)
は1000000です。
投稿2016/05/03 01:55
総合スコア902
0
256 は16進で 100 です。
式で8ビット左シフトを2回していますので、
1000000 になります。
これがリンク先の説明 の
「16進数で『1000000』を足すことによって」
になります。
補足
(256 + r << 8) は演算子の優先度から
256 + r の結果を 8 ビット左シフトです。
投稿2016/05/01 03:42
総合スコア674
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/02 01:24
2016/05/02 01:30
2016/05/03 01:19
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/03 01:40 編集
2016/05/03 03:09
2016/05/04 02:28