No.8ベストアンサー
- 回答日時:
★追記。
>これはこの処理では左にシフトしているため他のビットの値は何でもいいということでしょうか?
↑
左にシフトした後で (char) 型にキャストされるからです。
これは hi、lo 変数が char 型なので左シフトした9ビット以上が自動的にカットされるからです。
キャストを利用すると9ビット以上をカット出来るため 0xFF で AND を取るのと同じ効果があるのです。
同じ効果になるだけで『何でもいい』訳ではないのです。hi、lo が char 型以外だと 0xFF で
AND を取る必要があります。
・以上。
参考URL:http://www9.plala.or.jp/sgwr-t/c/sec14.html
No.7
- 回答日時:
★回答者 No.4 です。
・ちょっとマスク値の演算方法が間違っていました。訂正。
間違い⇒『mask = (char)(~0 >> (8 - 3));』
正しい⇒『mask = (char)(0xFF >> (8 - 3));』
※『~0』で11111111111111111111111111111111=0xFFFFが作れます。
※でも今回は1バイトの 0xFF の定数にした方が良さそうです。
>mask = (char)(0xFF >> (8 - 3));
↑
この mask には 0x07 がセットされます。
2進数では 00000111 です。
この 00000111 を作り出すためにの演算です。
ちなみに (8 - 3) の 3 がシフトする数です。
・nビットのシフトの場合は次のようにします。
mask = (char)(0xFF >> (8 - nBit));
これは次のようになります。
(1)『0xFF』は11111111(2進数)となります。
(2)(8 - nBit) で nBit=3 ならば (8 - 3)=5 となります。
(3)この値11111111(2進数)を右に5ビットシフトします。
すると00000111(2進数)となり0x0007(16進数)です。
(4)あとは mask に 0x0007 が代入されます。
・さて mask に 0x0007 が必要な理由ですが、これは『hi = (buf[i - 1] & mask) << (8 - 3);』で
使っています。この意味は分かりますか?
意味は右に3ビットシフトするため、配列の1つ前の下位3ビットを取り出すためのマスク値です。
前回は mask でビットANDを取っていますが、mask 値を使わずにキャストを使っても出来そうです。
サンプル:
unsigned char buf[ MAX_BUFF ] = { 0x30, 0xF0, 0x80, …, 0x12 };
int i = MAX_BUFF;
// 配列の後(うしろ)から処理
while ( --i > 0 ){
buf[ i ] = (unsigned char)((unsigned char)(buf[i - 1] << (8 - nBit)) | (buf[i] >> nBit));
}
buf[ i ] = (unsigned char)(buf[i] >> nBit);
※今回は mask 値を使わずに (unsigned char) キャストを利用しています。
これでも上手くいきます。多分こちらの方が分かりやすいかもしれない。
何度も丁寧に教えてくださってありがとうございます。
#4の回答を参考にして一応求める値が作れるようになりました。
本当に感謝しております。
ただmaskをつかわずに
『hi = (buf[i - 1] & mask) << (8 - 3);』⇒
『hi = (buf[i - 1]) << (8 - 3);』
でやっても結果は同じく正常になります。
これはこの処理では左にシフトしているため他のビットの値は何でもいいということでしょうか?
ここだけまだ少しもやもやしています。。。
No.6
- 回答日時:
修正します。
void shift(unsigned char src[], unsigned char dst[], int len, int bit){
int i = len - 1;
int j = bit / 8;
int b = bit % 8;
while(i > j){
dst[i] = src[i - j - 1] << (8 - b) | src[i - j] >> b;
i--;
}
if(i == j){
dst[i] = src[i - j] >> b;
i--;
}
while(i >= 0){
dst[i] = 0x00;
i--;
}
}
No.5
- 回答日時:
8ビット以上のシフト、結果の出力先指定ができます。
#include<stdio.h>
void shift(unsigned char src[], unsigned char dst[], int len, int bit){
int i = len - 1;
int j = bit / 8;
int b = bit % 8;
while(i > j){
dst[i] = src[i - j - 1] << (8 - b) | src[i - j] >> b;
i--;
}
dst[i] = src[i - j] >> b;
i--;
while(i >= 0){
dst[i] = 0x00;
i--;
}
}
int main(){
int i;
int len = 3;
int bit = 3;
unsigned char src[] = {0x30, 0xf0, 0x80};
shift(src, src, len, bit);
for(i = 0; i < len; i++)
printf("%x\n", src[i]);
}
No.4
- 回答日時:
★アドバイス
>ですと下位3ビットがなくなりますよね?
>この3ビットを次の配列に移動する方法がよく分からなくて・・。
↑
この場合は配列の後(うしろ)から処理します。
そして前の配列から下位3ビットをシフト演算します。
サンプル:
char buf[ 3 ] = { 0x30, 0xf0, 0x80 };
char hi, lo;
char mask;
int i;
// 右に3ビットシフトするためのマスク値
mask = (char)(~0 >> (8 - 3));
// 配列の後(うしろ)から処理
for ( i = 2 ; i >= 0 ; i-- ){
hi = (buf[i - 1] & mask) << (8 - 3);
lo = (buf[i - 0] >> 3);
if ( i != 0 ){
buf[ i ] = (hi | lo);
}
else{
buf[ i ] = (lo);
}
}
以上。
ご回答ありがとうございます。
// 右に3ビットシフトするためのマスク値
mask = (char)(~0 >> (8 - 3));
↑の行の意味がよくわかりません。
もしよろしければ簡単に説明していただけないでしょうか?
よろしくお願いします。
No.3
- 回答日時:
配列の数が3個で固定なら、long にセットしてビット
シフトでもいいですね
unsigned char buf[]={0x30,0xf0,0x80};
int n = 3;
long tmp;
printf( "%02x %02x %02x\n",buf[0],buf[1],buf[2]);
tmp = buf[0]; tmp<<=8;
tmp |= buf[1]; tmp<<=8;
tmp |= buf[2];
tmp>>=n;
buf[2] = tmp & 0xff; tmp >>=8;
buf[1] = tmp & 0xff; tmp >>=8;
buf[0] = tmp;
printf( "%02x %02x %02x\n",buf[0],buf[1],buf[2]);
No.2
- 回答日時:
配列の数、シフト数を汎用的に作るなら
#define COUNT 3
#define INDEX 3
int main(void){
int i, j, bit, tmp;
unsigned char buf[INDEX] = { 0x30,0xf1,0x80 };
for (i = 0; i < COUNT; i++) {
bit = 0;
for (j = 0; j < INDEX; j++) {
tmp = buf[j] & 1; /* 最下位ビットを保存 */
buf[j] >>= 1; /* 1ビットシフト */
buf[j] |= bit; /* キャリービットを追加 */
bit = tmp << 7; /* キャリービットを更新 */
}
}
return(0);
}
No.1
- 回答日時:
とりあえず、考え方だけ。
# まるまる答えを書いてしまうと、削除されてしまうかもしれませんので。。。
まず、ビットシフトは以下のようにすればできますよね。
========================================================
int hoge = 0x30;
int n = 3;
hoge >>= n; /* hoge == 0x06 */
/*------------------------------------
hoge >>= n; は
hoge = hoge >> n; と等価。
------------------------------------*/
========================================================
あとは、配列のインデックスで for でループをまわせばいけそうですけど、そういう話ではないのでしょうか?
この回答への補足
ご回答ありがとうございます。
>あとは、配列のインデックスで for でループをまわせばいけそうですけど、そういう話ではないのでしょうか?
for(i=0;i<3;i++){
buf[i] >>= n;
}
ですと下位3ビットがなくなりますよね?
この3ビットを次の配列に移動する方法がよく分からなくて・・。
素人質問ですみませんがよろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 数学 線形代数の対称行列についての問題がわからないです。 2 2023/01/08 14:59
- 数学 場合の数、確率 45 (浜松医科大学) 1 2023/07/29 13:52
- 物理学 あのこれは、間違いと 3 2022/11/13 12:22
- 数学 ハイネボレルの被覆定理、内田伏一著 「集合と位相」定理22.1 1 2022/07/07 10:49
- 情報処理技術者・Microsoft認定資格 2進数の問題を教えてください。 1 2022/07/27 09:42
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- 数学 x1+3x2+2x3=4 2x1+x2-3x3=2 -5x1+5x2+18x3=a 次の連立1次方程 2 2023/07/02 03:15
- 数学 数学(ベクトル) 単位ベクトルの一次結合で一般の空間ベクトルは表せる という式なのですがなぜ 「x1 3 2023/04/10 01:24
このQ&Aを見た人はこんなQ&Aも見ています
-
【お題】NEW演歌
【大喜利】 若い人に向けたことは分かるけど、それはちょっと寄せ過ぎて変になってないか?と思った演歌の歌詞
-
あなたにとってのゴールデンタイムはいつですか?
一週間の中でもっともテンションが上がる「ゴールデンタイム」はいつですか? その逆で、一週間でもっとも落ち込むタイミングでも構いません。 よかったら教えて下さい!
-
これ何て呼びますか Part2
あなたのお住いの地域で、これ、何て呼びますか?
-
おすすめのモーニング・朝食メニューを教えて!
コメダ珈琲店のモーニング ロイヤルホストのモーニング 牛丼チェーン店の朝食などなど、おいしいモーニング・朝食メニューがたくさんありますよね。
-
タイムマシーンがあったら、過去と未来どちらに行く?
20XX年、ついにタイムマシーンが開発されました。 あなたは過去に行く? それとも未来? タイムマシーンにのって、どこに行って、何をしたいか教えてください!
-
C言語において、 配列要素をひとつずつ前にずらすコード
C言語・C++・C#
-
C言語で128bitの2進数のビット演算をしたいのですが、intのように1つの数として定義できますか?
C言語・C++・C#
-
関数から配列を返すには?
C言語・C++・C#
-
-
4
C言語 配列の長さの上限
C言語・C++・C#
-
5
16進数 加算 減算 C言語
C言語・C++・C#
-
6
ビットをローテートするプログラムの解説をお願いします。(C言語)
C言語・C++・C#
-
7
配列の要素数に変数を入れたいときには
C言語・C++・C#
-
8
python エラー
その他(プログラミング・Web制作)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CStringをwchar_tに変換したい
-
C言語プログラミングについて(...
-
配列をnビットシフトする
-
'const char *' 型は 'char *' ...
-
charでの計算?
-
型変換
-
C言語のfor文です。 繰り返しの...
-
3桁区切(コンマ)記号をつけ...
-
switch文で文字を比較すること...
-
テキストデータをそのままバイ...
-
干支のプログラム
-
charからLPTSTRへの変換方法
-
char型と言うものがまだ理解出...
-
ネットワークにつながっている...
-
Visual Studio strcpyについて
-
構造体のアライメント調整
-
絶対パスからのファイル名の切...
-
c言語の問題の説明、各所ごとに
-
日付表示の方法
-
_TCHAR*での引数の読み込み
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
charでの計算?
-
文字列から空白を取り除きたい...
-
CStringをwchar_tに変換したい
-
C言語のfor文です。 繰り返しの...
-
charからLPTSTRへの変換方法
-
fgetsなどのときのstdinのバッ...
-
'const char *' 型は 'char *' ...
-
間接参照のレベルが異なっています
-
double型の値をchar配列に変換...
-
atoi( ) の反対をやりたい
-
間接操作のレベルとは
-
ネットワークにつながっている...
-
型変換
-
テキストデータをそのままバイ...
-
文字列ポインタを結合
-
C言語です
-
3桁区切(コンマ)記号をつけ...
-
Win32APIでのエディットボック...
-
TCHAR文字列?の特定部分の数字...
-
絶対パスからのファイル名の切...
おすすめ情報