
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も見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
宣言による処理の重さ
-
getchar()を int でとる理由...
-
c言語
-
ConvertINetStringについて
-
MFCでのBITMAP作成について
-
for文 アスタリスクで形を作る
-
char* を渡したとき、不適切なP...
-
ワイルドカードを用いた文字列検索
-
YUV⇔RGB変換がうまくいきません。
-
C言語エラーについて
-
アドレスの中身を参照する方法
-
あるシーケンスに含まれるある...
-
配列から指定するデータを取り...
-
メモリの再確保について
-
C言語について
-
LCD表示の制御
-
strcmp と strcpy の使い方で疑問
-
コマンドラインに入力されてい...
-
phpMyAdminからストアドプロシ...
-
sprintfに同じ変数は使えるか
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
文字列から空白を取り除きたい...
-
CStringをwchar_tに変換したい
-
charからLPTSTRへの変換方法
-
テキストデータをそのままバイ...
-
c++ 文字列を入力して、一文字...
-
'const char *' 型は 'char *' ...
-
間接操作のレベルとは
-
WORDをcharに変換する方法
-
strncpyと_tcsncpy_sのヌルの扱...
-
型変換
-
配列をnビットシフトする
-
atoi( ) の反対をやりたい
-
Win32APIでのエディットボック...
-
間接参照のレベルが異なっています
-
c言語配列の結合についてです。...
-
【C言語】テキストファイル内の...
-
double型の値をchar配列に変換...
-
switch文で文字を比較すること...
-
C言語のfor文です。 繰り返しの...
おすすめ情報