- ベストアンサー
サンプルプログラムにあったビット和の意図
あるサンプルプログラムで出てきた記述なのですが aaa =bbb | 0; ccc = ((ccc * 1000) | 0) * 0.001; ここで使用されている「|」の意図がわかりません。 「|」自体がビット和の演算子であることは理解しています。 ですが「| 0」とした場合、値は何も変わらないのではないでしょうか? 何か特別な意図があるのでしょうか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
いやいや。 基本の考えは一緒でも、記述方法が違うこともあるし 同じ記述に見えて、実際の動作が違うこともあります。 今回の場合も C/C++ → | 演算では、実数型(double,float)は使えない。 Javascript → | 演算では、整数に変換されて、計算される という違いがあります。 そのサンプルコードでは、この「整数に変換」という効果だけを使おうとしています。そのための、0でのor演算です。
その他の回答 (4)
- k_kota
- ベストアンサー率19% (434/2186)
>ここではJavaScript記述となっていますが、 基本的な考え方は変わらないと考えているため、 C、C++カテゴリで質問しています これは間違いです。 こういったところは言語に非常に左右されます。 javascriptであれば必要な処理になります。 基本的な考え方、と言うのはアルゴリズムについては変わりませんが、 データ構造という点では当てはまらない場合が多いです。
お礼
ご回答ありがとうございます。 どっちの言語の説明を見てもビット演算だったので、 大丈夫かなと思ってましたが、浅はかでした。 次回以降は、的確なカテゴリに質問するように心がけます。
- Tacosan
- ベストアンサー率23% (3656/15482)
ビット演算は規格上オペランドとして汎整数型を要求しますから, ccc が float や double (や long double) などの型であるときには下の式はコンパイルエラーになるのが正しい動作です>#2. そして整数拡張により ccc の型がどうであろうと ccc*1000 の型は少なくとも int になるので, こっちの「0 とのビット和」は完全に無意味です. 上の方も無意味だと思うけど.... 少なくとも代入演算子のオペランドとして bbb を評価しないといけないし, ・その結果として整数拡張されて int (以上) になる ・どうせ左辺の aaa にあわせて型変換される のどちらかの理由でやっぱり「0 とのビット和」は意味がないような気がする. #2 の最後で触れられている, 「組み込み系だったら~」の部分も含めて完全に #2 に同意.
- kmee
- ベストアンサー率55% (1857/3366)
どちらも意味が無いと思われます。 #1さんのような意図があったとしても、 aaa=bbb|0は、bbb|0でサイズを合せなくても、 aaa=bbbと代入するだけで暗黙のキャストでaaaに合わされます(可能な場合) ccc = ((ccc * 1000) | 0) * 0.001;は式全体が意味不明です。 cccを1000倍して整数化(小数点以下切り捨て)→0.001倍、で、小数点以下3位に揃えているようにも見えます。 ですが、cccが実数型(double,float)だと、ccc*1000は実数となり、|による演算が使えません (少なくとも、手許のgccではエラーになります) cccが整数型なら、そもそも小数点以下が無いので、この計算をしても値は変化しません (おそらく。もしかしたら、浮動小数点演算時の誤差が出る場合も) 何のサンプルコードか、情報を公開してはどうでしょうか。もちろん、支障の無い範囲で。 もしかしたら、これが重要な意味を持つ処理系があるかもしれませんが、私は知りません。 (組込みマイコン用とかで、何か意味がある、とかの可能性はありそうです)
補足
ご回答ありがとうございます サンプルコードの詳細は http://jsdo.it/calmbooks/controllerStick 少々わかりづらいですが、 ↑のサイト(IE7等のブラウザでは見れないかもしません)の 中央付近のタブ「JavaScript 226 lines」をクリックし、 表示されたソースの 155行目、168行目となります。 ここではJavaScript記述となっていますが、 基本的な考え方は変わらないと考えているため、 C、C++カテゴリで質問しています
- chie65536(@chie65535)
- ベストアンサー率44% (8741/19839)
定数の「0」は「int型」なので、演算の結果は「最低でもintサイズになる事」が保証される。 言わば「int型へのキャスト」と近い働きがある。 「int型への型キャスト」と異なるのは「|の左辺がintよりも大きいサイズの時、そのサイズが保持される」と言う点。 例えば aaa =bbb | 0; の構文で「bbbがunsigned charだった」としよう。 「0はintサイズ」なので「bbb | 0」の結果は、大きいほうのサイズである、intサイズが保証される。 同一の構文で「bbbがintよりもサイズが大きいlongだった」としよう。 「0はintサイズ」なので「bbb | 0」の結果は、大きいほうのサイズである、longサイズが保証される。 一方、 aaa =(int)bbb; の構文の場合、話は違う。 「bbbがunsigned charだった」なら、結果はintサイズ。これは上記と一緒。 「bbbがintよりもサイズが大きいlongだった」場合も、結果はintサイズになっちゃう。これは上記とは異なる。 このように「値が変わらないけど、型が変わる。しかも、明示的キャストと違い、式中の最大サイズの型が保証される」と言う作用があるので「型だけ変えたい」と言う意図でやっていると思う。
お礼
ご回答ありがとうございます。 どっちの言語の説明を見てもビット演算だったので、 大丈夫かなと思ってましたが、浅はかでした。 同じと考えたらなら、C/C++カテゴリのほうが回答ユーザ数が多い、 というイメージがあったので、回答も得られやすいかと思いまして・・・ 実質は整数にキャストする方法として ビットのor演算を使用しているという認識でいいんですね? (早まって、回答閉めきってしまったので、お返事は出来ないと思われますが)