QBitArray
は、他のものに変換できるようには設計されていません。その内部表現は確かに内部的なものです。
あまりにも簡単です。現代のアーキテクチャはバレルシフタを使用しているので、シフトは安いです。
可能なビットからバイトへのマッピングはいくつかあります。したがって
byte 0 byte 1 byte n-1 byte n
LL - [] [89ABCDEF] ...
LB - [] [FEDCBA98] ...
BL - ... [89ABCDEF] []
BB - ... [FEDCBA98] []
::のは、それらのすべてをカバーしてみましょう
enum class BitMapping { LL, LB, BL, BB };
bool getBit1(const QByteArray & arr, int bit, BitMapping m) {
Q_ASSERT(arr.size() >= 8);
auto byte = (m == BitMapping::LL || m == BitMapping::LB) ?
bit/8 : (7 - bit/8);
bit = (m == BitMapping::LB || m == BitMapping::BB) ?
(bit%8) : (7 - (bit%8));
return arr.at(byte) & (1<<bit);
}
私たちはプラットフォームが64ビット整数のための賢明なサポートを持っていると仮定した場合、我々はそれらを活用することができます
bool getBit2(const QByteArray & arr, int bit, BitMapping m) {
Q_ASSERT(arr.size() >= 8);
auto value = *reinterpret_cast<const quint64 *>(arr.data());
if (m == BitMapping::LL || m == BitMapping::BL)
bit = (bit & 0x38) + 7 - (bit & 0x07); // reorder bits
if ((Q_BYTE_ORDER == Q_LITTLE_ENDIAN && (m == BitMapping::BL || m == BitMapping::BB)) ||
(Q_BYTE_ORDER == Q_BIG_ENDIAN && (m == BitMapping::LL || m == BitMapping::LB)))
bit = (bit & 0x07) + 0x38 - (bit & 0x38); // reorder bytes
return value & (1<<bit);
}
どれでもまともなコンパイラは、上記のいずれかの実装を特殊化した場合にインライン展開します。
bool getBit(const QByteArray & arr, int bit) {
return getBit2(arr, bit, BitMapping::LB);
}
またLB
場合の手でそれを特化することができます:Q_BYTE_ORDER
チェックはコンパイル時の定数であり、何の実行時のオーバーヘッドが発生しないことを
bool getBit1(const QByteArray & arr, int bit) {
Q_ASSERT(arr.size() >= 8);
auto byte = bit/8;
bit = bit%8;
return arr.at(byte) & (1<<bit);
}
bool getBit2(const QByteArray & arr, int bit) {
Q_ASSERT(arr.size() >= 8);
auto value = *reinterpret_cast<const quint64 *>(arr.data());
if (Q_BYTE_ORDER == Q_BIG_ENDIAN)
bit = (bit & 0x07) + 0x38 - (bit & 0x38); // reorder bytes
return value & (1<<bit);
}
注意。
getBit1
およびgetBit2
は、Qtが実行されるすべてのプラットフォームで移植可能です。getBit2
は、getBit1
より少し良いコードを生成します。 x86-64では、getBit2
のビットツイイドコードは5命令になります。
mov $0x1,%eax
shl %cl,%eax
cltq
test %rax,(%rdi)
setne %al
retq
質問に現在のコードを追加してください。私はビットの値を知るためにビット単位の演算子を使用していないのはなぜだろうかと思います。 http://stackoverflow.com/a/523737/2266412 –
これは、私が生の 'QByteArray'ビットチェックを探しているところで' int'を受け付けるためです。まず、ビットがある特定のバイトを見つけてintに変換してから、そのメソッドを使用する必要があります。バイト位置とビット位置では、ロジックを把握する必要があります。パフォーマンスが関心事ですので、私はより直接的かつ迅速なものを求めています。 私は現在のコードを説明しましたが、私はそれをまったく使用するつもりはありません。それは面倒なので、私はそれを投稿することは全く利益がないとは思わない。 – mrg95
あなたが話している "論理"は、現代のCPUでは些細なことです。あなたは本当にhttps:// godboltに向かうべきです。あなた自身のために見てください。 –