DATE : 2006/10/30 (Mon)
java.lang.CharSequence というインタフェースがあります。
このインタフェースは、Java で文字列を表す String クラスや、可変の文字列データの StringBuilder、char 型のデータ列を表す CharBuffer などが実装しており、文字列データを統一して扱えるという点で便利です。
例えば、正規表現を扱う java.util.regex パッケージでは、操作対象として CharSequence を要求します。つまり、String であっても CharBuffer であっても正規表現を使った操作が可能です。
しかし、CharSequence では equals メソッドが定義されていません。つまり、CharSequence 同士で同じ文字列データを表すかどうかを確かめることはできません。
例えば、あるバイト列が特定の文字列を表すかどうかをテストするコードを書いたとします。
// ・string は比較対象の文字列 // ・byteData は、バイト列を表す ByteBuffer オブジェクト // ・encoding は、文字エンコーディングを表す Charset オブジェクト CharBuffer stringData = encoding.decode(byteData); Assert.assertEquals(string, stringData);
「Assert#assertEquals(Object, Object)」は、JUnit の API で、引数に指定されたオブジェクトが同じものかどうか、Object#equals メソッドを使ってテストします。
しかし、例え stringData に正しく string の文字列データが復元できたとしても、このテストは失敗します。
それでは、テストを成功させるためにはどうすれば良いでしょうか。CharSequence には toString メソッドが定義されています。toString メソッドは CharSequence で表される文字列データを String オブジェクトとして返します。すると、以下のようにすればテストは成功します。
CharBuffer stringData = encoding.decode(byteData); Assert.assertEquals(string, stringData.toString());
そのため、CharSequence 同士を比較する際には、toString メソッドを使って String オブジェクトに変換してから比較することになります。
DATE : 2006/10/29 (Sun)
BREW API の IPOSDET_GetGPSInfo 関数を使用すると、AEEGPSInfo 構造体に経緯度などの位置情報を取り出すことができます。
しかし、AEEGPSInfo に格納されている経緯度は度単位であるにもかかわらず、整数値で格納されています。(浮動小数点数形式への変換は、WGS84_TO_DEGREES マクロ関数を使用します)
この整数は、BREW API のドキュメントによると緯度は 180/2^25 度、経度は360/2^26度として表されているようです。
ところで、この180/2^25や360/2^26という数字はどこから出てきたのでしょうか。API ドキュメントによると、『TIA/EIA IS-801規格に準拠』と書いてあります。この規格番号を基にウェブ検索してみると、『3GPP2 C.S0022-0 Position Determination Service Standard for Dual Mode Spread Spectrum Systems』(PDF)という規格書が見つかりました。
この文書を拾い読みしたところ、180/2^25度単位、360/2^26度単位とすることで、緯度は25ビット幅、経度は26ビット幅で表現できるそうです。
すると、経緯度の情報をデータとして格納しておきたい場合は、この規格の形式で格納しておくと便利です。あらかじめビット幅が分かっていますし、BREW で取得できる形式と互換性があるところも利点です。
( ´∀`)経緯度の演算をする際にも、整数のままで計算できますしね
ちなみに、経緯度を TIA/EIA IS-801 形式に変換するには、経緯度にそれぞれ186413 を乗じます。
(TIA/EIA IS-801形式) = (経緯度) × 186413
経緯度は度単位です。また、計算結果に小数があれば切り捨てます。
なお、「186413」という数字は、180/2^25 および 360/2^26 の逆数から小数を切り捨てたものです。
(注:規格書を全て読んだわけではないので、この部分が規格にあるかどうかはまだ確かめていません。ただ、BREW の GPS エミュレーションはこの式のように動作していました)
ちなみにこの形式の場合、TIA/EIA IS-801 形式の1は1.93×10^-2秒に相当します。つまり、これ未満の経緯度は TIA/EIA IS-801 形式では表現できないことになります。日本付近の地表面では、経緯度の1秒はだいたい30m前後に相当するそうです。すると、約60cm 前後以下の距離は TIA/EIA IS-801 形式では表現できません。
ただ、携帯端末に搭載されている GPS 受信機の精度(受信機単独での測位で10m~30m前後、基準局からの補正で数m)を考えると、これでも十分だと言えます。
参考文献
DATE : 2006/10/28 (Sat)
( ^ω^)「MUSASHI -GUN道-」第24話「金の城」を見ました。作画崩壊が有名な MUSASHI の中でも第1話以上のクオリティーを見せてくれたとても稀有な回です。
(;^ω^)もちろん、普通にホメ言葉です。MUSASHI に向かって「高いクオリティー」というと、なぜか恐ろしく作画崩壊しているように聞こえるので不思議ですね
ちなみに、原画を担当した会社は「アンサー・スタジオ」です。ウェブサイトを辿っていくと、創立秘話がありました。
(;゚Д゚)「ウォルト・ディズニー・アニメーション(ジャパン)」の閉鎖を受けて作られた会社だそうです
(;^ω^)予算が余ってしまったのでしょうか……
ちなみに、第17話では、登場人物の一人が「アンサーチャンスは、1回きりだぞ」という言葉を残しています。アンサー・スタジオによる作画を予言した言葉として、MUSASHI 名言集に登録されています。
それにしても、いつも作画崩壊状態の MUSASHI ですから、この回はより際立って見えました。( ´∀`)素直に普通のアニメとして楽しめましたね。
(;^ω^)もっとも、話の内容そのものは、いたって普通の MUSASHI でしたが……
DATE : 2006/10/26 (Thu)
BREW アプリケーションに使うデータファイルとして、バイナリファイルを作ろうとしていたらミスしてしまいました orz
BREW アプリケーションを実行する CPU は、PC とは異なり ARM を使用します。そのため、バイナリファイルを作る上でいろいろと考えなければならないことが出てきます。
例えば、バイトデータを配置する方式のエンディアン。開発機の PC に使われていることが多い x86 系 CPU ではリトルエンディアンですが、ARM アーキテクチャの場合はリトルエンディアン、ビッグエンディアンの両方が混在しているようです。実際、BREW を実行する実機のエンディアンは機種依存になっています。
しかし、BREW API には、実機のエンディアンにバイト列を変換する関数が用意されています。そのため、バイナリファイルのエンディアンを定めておけば、この点は特に問題になりません。
この問題には早々から気付いていたので簡単に解決できたのですが、もうひとつの問題となる、値のビット幅には見落としてしまいました orz
BREW API では、整数型のビット幅は型によって規定されています。つまり、「int32」や「uint16」という型が定められており、それぞれ32ビット整数型、16ビット符号なし整数型を表しています。
しかし、浮動小数点に関しては、ビット幅が定められていません。ただ単に、「double」という型があるだけです(BREW では、float は使えません。浮動小数点を扱う際には、double を使うことになります)。C や C++ において、double 型のビット幅は機種依存です。
そのことを、double 値を書き出すバイナリファイルの仕様を策定して実装している最中に気が付きました orz
(;^ω^)バイナリファイルを書き出すプログラムは Java で作っていたので、余計に気付きにくかったのかもしれません。(Java の場合、double 型は64ビットと決められています)
とりあえず考えてみた解決方法は以下の通りです。
- 浮動小数点を文字列として書き出す(BREW API には、文字列を解析して double 型に変換する関数があります)
- 固定小数点数にして、整数型として書き出す
DATE : 2006/10/25 (Wed)
(前回の記事)
Brew Test Unit の構成
Brew Test Unit は主に次の要素から成り立っています。
- テストケース
- テストスイート
- テストリザルト
- テストリスナ
- テストケース(CppUnit::TestCase, UnitTestCase.h)
- テストを記述するためのクラスで、テストを実行するクラスの基底クラスとして使用します。(「テストケースの基本」参照)
- テストスイート(CppUnit::TestSuite, UnitTestSuite.h)
- 登録されたテストケースを実行していくクラスです。
- テストリザルト(CppUnit::TestResult, UnitTestResult.h)
- テストの結果(成功・失敗)を記録するクラスです。テストの実行時にテストスイートに渡すことで、結果を記録します。
- テストリスナ(CppUnit::TestListener, UnitTestListener.h)
- テスト全体の開始・終了やテストの失敗などのイベントを受け取るクラスです。Brew Test Unit には、ファイルに出力を行う FileListener(filelistener.h)や、デバッグ情報に出力を行う StandardListener(standardlistener.h)がテストリスナとして用意されています。
(つづきます)