目次: Java
今日はJavaでビットフィールドを扱う方法を探していたのですが、やり方がわかりません。
#include <stdio.h>
union u {
char c;
struct _s {
unsigned a:2;
unsigned b:4;
unsigned c:2;
} s;
};
int main(int argc, char *argv[])
{
union u v;
v.s.a = 1;
v.s.b = 0;
v.s.c = 1;
printf("v.c=%d(0x%x), v.s.b=%d(0x%x)\n",
v.c, v.c, v.s.b, v.s.b);
v.s.b = 10;
printf("v.c=%d(0x%x), v.s.b=%d(0x%x)\n",
v.c, v.c, v.s.b, v.s.b);
return 0;
}
Cだと上記のように構造体風に書けるんですが、Javaだとどうすりゃいいんだろか。今は仕方ないのでシフトとビット演算でえっちらおっちら書いています。
目的はある下位ビット(stビット目とする)からある上位ビット(edビット目とする)を占めるビットフィールドを抜き出すことです。これはビットフィールドの書き換え、つまり上記のCでいうところのv.s.b = 10; のような処理をしたいときに必要です。
もう一つの目的はビットフィールドに入っている値を得ることです。これはビットフィールドを読み取り、つまりprintf("%d", v.s.b); のような処理をしたいときに必要です。
まずstビット以上を1で埋めたパターン(パターンAとする)を作ります。
作り方: 1をstビット左シフトして1を引くと、stビットより下が1で埋まったパターンが得られますので、そのパターンをビット毎NOTをするとパターンAが得られます。
次にedビット以下を1で埋めたパターン(パターンBとする)を作ります。
作り方: 1をedビット左シフトして1を引くと、edビットより下が1で埋まったパターンが得られます。そのパターンに1をedビット左シフトした値をビット毎ORすると、パターンBが得られます(※)。
パターンAとパターンBのビット毎ANDを取ると、stビットからedビットまでが1で埋まったマスクが得られます。
ビットフィールドを保持している値とマスクをビット毎ANDすると、目的のビットフィールド以外を0で潰した値が得られます。
ビットフィールド内の値を得たい場合は、パターンBだけビット毎ANDして、その後stビット論理右シフトします。パターンAをANDしなくても結果は同じです。
例としてst = 2, ed = 5の状態を図示すると上記のようになります。
おそらく「何やってるんですかJavaなら○○で一発ですよ!」ってオチがある気がしてならないので、もっと良いやり方があったらぜひ教えてくださいまし。
(※)1をed + 1ビット左シフトして1を引く方法は正常に計算できない場合があります。edと変数のビット長が等しい場合、(変数のビット長 + 1) ビットの左シフトが起きます。CやJavaでは変数のビット長を超える左シフトの結果は不定のため、得られるパターンも不定となります。
この記事にコメントする
昨日の日記のお母さんのコメント「DSはもう少し画面が大きいと良いのに。」を見てふと思ったこと。
先日発売された新型機DSiでは画面が少し大きくなりました。ということは任天堂は画面が小さいという問題を認識していて、改善する意志もあるんです。なのにもっと画面を大きく(例えば倍くらい)できないのはなぜ?
あまりでかいと持てない、など理由は色々あると思いますが、大きな理由は初代DSやDS Liteと同じ環境を保つため、でしょう。
環境を保つと何が嬉しいかというと、初代DSで遊べるゲームが新型機のDS LiteやDSiでも遊べるようになります。逆に環境を保たないと、新型機で性能や機能(画面サイズなど)を変えると、過去のゲームが破綻して遊べなくなってしまいます。
より良く変えることが出来るのに、変えられない…新型機で過去のゲームが遊べることは当たり前に見えて、結構大変なのです。
ゲーム機は一度流行れば5年は持ちますから、基本となる初代機のスペック決めは非常に重要です。とはいっても、5年間使われるスペック決めってどうやるんですかね?相当難しいよね?
この記事にコメントする
大下さんと2人でハンドミキサーを買いに行きました。ヨドバシのポイントだけで買えてしまいました。思いのほか安かった。
いつぞやメレンゲを泡立てるのは大変という話をしていたので選んだつもりでしたが、大下さんは「お菓子を作って俺に喰わせろ。」という意味だと思っていたようです。とりあえずお菓子を作ってくれることには変わりないです。
誕生日特典を利用して、京831(やさい)倶楽部(大阪市西梅田、ブリーゼタワー5F)のコースを格安で。名前の通り野菜がメインでうまいです。タケノコが甘いなんて初めて知った。
テーブル上にろうそくがあり、料理が出てくる合間にいたずらしていたら、ろうそくの芯が折れて火が消えてしまいました。ご迷惑かけました…。
ニンテンドーDSiを買いました。個人的にはWPA-PSK(AES/TKIP) に対応しているのがグッド。
カメラは何に使うか良くわかりません。面白いかどうかは別として、カメラとWi-Fiとマイクがあるので、ゲーム+テレビ電話(上画面に人、下画面に対戦画面)ができそうですね。いよいよ携帯電話と携帯ゲーム機の垣根が低くなってきたなあ。
ゲームもついでに買いました。マリオ&ルイージRPG 3です。Aでマリオを動かして、Bでルイージを動かします。操作は簡単なのにタイミングがよくわからず、しょっちゅう押し間違えて敵にボコボコにされます。
この記事にコメントする
誕生日を祝っていただきました。皆様ありがとうございます。
今まで30歳になるなんて考えたこと無かったけど、30歳はもうすぐなんだよなあ…。
この記事にコメントする
| < | 2009 | > | ||||
| << | < | 03 | > | >> | ||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
| 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 | - | - | - | - |
wiki
Linux JM
Java API
2002年
2003年
2004年
2005年
2006年
2007年
2008年
2009年
2010年
2011年
2012年
2013年
2014年
2015年
2016年
2017年
2018年
2019年
2020年
2021年
2022年
2023年
2024年
2025年
過去日記について
アクセス統計
サーバ一覧
サイトの情報合計:
本日: