質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.80%

[C++]BYTE配列のビット操作

解決済

回答 6

投稿

  • 評価
  • クリップ 0
  • VIEW 10K+

09logic

score 14

プログラミング初心者です。C++の質問なんですが、ただいま困っています。
BYTE型の配列から、任意の位置のbitから任意の数だけbitを読み込み、
読み込んだbitを10進数に変換したいのですが、やり方がわかりません。

例えば、
BYTE byteArray[4];
↑この配列には、
[0] = 10101010
[1] = 11101010
[2] = 11010001
[3] = 10101011
というデータが入っているとして(適当)、

int BitLen = 10;       // 任意の数
int BitPosition = 10; // 任意の位置

↑上記のような設定だと、読み込むbitは
[0] = 10101010
[1] = 11101010
ここから   ↑
[2] = 11010001
ここまで ↑
[3] = 10101011

上記のように読み込み、読み込んだbitは0010001010となって、
これを10進数に変換したいです。いろいろ考えましたが、いまいちやり方がわかりません。
どなたか、ご助力のほど宜しくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kopio

    2016/07/20 09:03

    どこをどう取ったら「0010001010」になるか教えてください。
    すっごくもやもやしてすっきりしません。

    キャンセル

  • 09logic

    2016/07/20 18:43

    回答が遅くなり申し訳ありません。
    0010001010についてですが、これは間違いですね。起きてすぐに質問を書いたからかも分かりませんが、自分のミスです。申し訳ありませんでした

    キャンセル

回答 6

+2

質問文の読み方が悪いのかビット列のどこを取っても0010001010という並びが出てこないのでビット列の前後をどう解釈するのかなど細かい仕様が読み取れないのですが、総論で。

問題を3段階に分けると易しくなります。
・配列からi番目のビットを取り出す
・ビット並びを数値とする
・数値を十進化する
こうですね。

最初の課題は、上に書いた通りで、何を持ってi番目とするのか、の仕様を質問者様しか把握していないことなので、これはお任せします。
int bit_at(int i);
という形式の関数かマクロにしたことにしましょう。

2番目の課題です。
こうなりますね。

int result = 0;
for(int i = 0; i < bitLen; ++i)
{
  result |= (bit_at(i + bitPosition) << i);
  // もしくは、こういう意図ですかね?
  // result |= (bit_at(i + bitPosition) << (bitLen - i - 1);
}

最後に、十進化するのはおなじみpritfです。

printf("%d\n", result);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/20 18:45

    問題を分けると分かりやすいですね。
    勉強になります、ありがとうございます。

    キャンセル

checkベストアンサー

0

byteArrayの配列を1つつながりと考えて(例えば4バイト分の配列なら32ビット分)、その連続したビット列の先頭(LSB)から数えてN個目のビットからM個のビットを取り出して数値に直す、ということですね?

いろいろやり方はあるかもしれないけれど、1つの方法としてまず配列の各要素を2進数の文字列に変換してそれを全て1つの文字列として連結し、文字列のお尻から先頭に向かってN個目の文字から先頭に向かってM個の文字を切り出し、それを数値変換する、という方法が考えられます。

アルゴリズムの勉強になるのであとは自分で考えてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/20 18:50

    ご回答いただきありがとうございます。
    皆さんに頂いたご回答から、色々考えましたが、今回は文字列化してそれを数値変換する方法にしました。
    皆さま、本当にありがとうございます。また機会があればよろしくお願いします。

    キャンセル

0

こんな回答が欲しいんじゃないことは百も承知で:

#include <iostream>
#include <bitset>
#include <string>
using namespace std;

int main() {
// 文字列化したbit列の10番目から10文字を取り出し、数値に変換して出力
  cout << bitset<64>(string("10101010111010101101000110101011").substr(10,10)).to_ulong();
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/20 07:32

    なるほど・・・。
    調べろと言われそうですが、BYTE配列を二進数の文字列で表現する方法はあるのでしょうか?もしご存知でしたら教えていただけませんでしょうか。。

    キャンセル

0

8 ビットですので、スタートするのは 8で割った商番目の要素の余り番目(0 ベース)のビットです。
11010011 の 2 番目のビット(0 ベースなので、一番右を 0 番目、その左隣を 1 番目と呼びます。つまり右から数えて 3 番目のことです)が知りたければ、1 << 2 と & を取り、結果が 0 であれば該当ビットは 0、0 以外であれば 1 となります。

10 番目の場合は、8 で割った商が 1、余りが 2 なので、[1] と 1 << 2 の & で出ます。

同様にして 11 番目 12 番目それ以降も出ますので、後はループに入れたら完成です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/20 07:30

    ご回答ありがとうございます。
    参考にいたします。

    キャンセル

0

4バイト固定ならuint32_t型の整数に突っ込んで32bitの符号無し整数として扱うのはだめでしょうか?リトルエンディアンであるとか1バイト=8ビットであるとか処理系依存になるかもしれませんが、BYTEってそもそもVC++の特有の処理系依存の型なので、問題ないかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/20 18:46

    ご回答いただきありがとうございます。
    参考に致します。

    キャンセル

0

BYTE配列を二進数の文字列で表現する方法はあるのでしょうか?

#include <iostream>
#include <bitset>
#include <string>
using namespace std;

int main() {
  unsigned char bytes[4] = { 0xAA, 0xEA, 0xD1, 0xAB };
  string result;
  for ( unsigned char byte : bytes ) {
    result += bitset<8>(byte).to_string();
  }
  cout << result << endl;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/20 18:45

    ご回答ありがとうございます。
    参考に致します。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る