🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

2回答

1307閲覧

bit列から塩基配列への符号化

grape_ll

総合スコア83

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

1クリップ

投稿2020/12/05 01:29

0,1からなる文字列を符号化して塩基にするコードを見ているのですが,以下に示すswith文の条件がよくわかりません.
2進数で表して0ならA,1ならC,2ならばG,3ならばTにするという考え方は理解できるのですが,なぜこの書き方でそうなるのかが分かりません.

C

1 unsigned char c1, c2, res; 2 for(int i=0; i<ORGDATA_LEN; i+=2){ 3 c1 = getc(ofp); 4 c2 = getc(ofp); //ofpから一文字読み取り 5 6 switch( ( (c1 & 0x1) << 7) >> 6 | ( c2 & 0x1) ){ 7 case 0: 8 res = BASE_A; 9 break; 10 case 1: 11 res = BASE_C; 12 break; 13 case 2: 14 res = BASE_G; 15 break; 16 case 3: 17 res = BASE_T; 18 break; 19 } 20 fputc(res, efp); 21 }

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

switch((c1 & 0x1) << 1 | ( c2 & 0x1) )
でいい気はしますが・・・
EOF の検出ができてないから、そのあたりの対策しようとした残骸では?
結局、i<ORGDATA_LEN で制御するようにしたんじゃないでしょうか?

まあ、あくまで予想ですが。

投稿2020/12/05 02:13

PingHermit

総合スコア478

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

grape_ll

2020/12/05 02:25

unsigned char は8ビットなので7ビットシフトしてから6ビット戻せばEOF=-1だった時にcaseに入らなくすることが出来ていたけど,i<ORGDATA_LEN で制御するようにしたので必要なくなってしまったという認識で合っていますでしょうか.
PingHermit

2020/12/05 02:50

あくまで予想です。 0x1 は、たしか int なので、int で計算されますからね。 うまく行かなかったのでしょう。
grape_ll

2020/12/05 06:03

頭に入れておこうと思います.
PingHermit

2020/12/05 08:30

そうしましょう。 どうみても、今は必要ない無駄なコードだと思います。 ですから残骸と思います。
fana

2020/12/07 04:38

EOF対策という話の意味がわからないです. EOF(0xFFFFFFFF)をunsigned char c1に突っ込むと,c1の値は0xFFになるわけで, (c1&0x1) は 0x00000001 となり, これを7bit左シフトしてから6bit右にシフトすることには何の意味も無いと思うのですが…?
PingHermit

2020/12/07 09:14

ですから残骸だと思います。 >fana switch((c1 & 0x1) << 1 | ( c2 & 0x1) ) でいいのに、変なことやって出来なくなったときの残骸という意味です。 現在動いてるからいいやレベルの。 まともなプログラマなら、ここでファイル終端・エラーチェック入れるでしょう。 入れたかったけど入れられなかった名残だと思いますけどね。
fana

2020/12/07 10:07

意味合いはわかりました. > unsigned char は8ビットなので7ビットシフトしてから6ビット戻せばEOF=-1だった時にcaseに入らなくすることが出来ていたけど という認識が「?」と思ったので.
guest

0

ベストアンサー

まず、
(c1 & 0x1)
という操作ですが、これは、c1が'0'なら0を、'1'なら1とする、ということはわかるでしょうか。
それを前提に、
( (c1 & 0x1) << 7) >> 6 | ( c2 & 0x1)
という式は
((c1 & 0x1) << 1)| (c2 & 0x1)
ってことですんで、
これは、
c1,c2が、'0','0' であれば、0
c1,c2が、'0','1' であれば、1
c1,c2が、'1','0' であれば、2
c1,c2が、'1','1' であれば、3
となる式ですね

投稿2020/12/05 01:48

編集2020/12/05 01:54
y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

grape_ll

2020/12/05 01:56

ANDの演算は分かります. 疑問点が三つほどありまして, unsigned charなのに数値として取られてるのはなぜか. 数値が二進数で読まれているのはなぜか. なぜ7回左シフトした後に6回右シフトしているのか.おっしゃっているように結果的には左に一回シフトで足りる気がするのにわざわざやっているということは何かし理由があると思うのですが,私はやったことがないのでわからないです.
y_waiwai

2020/12/05 02:01

charというのは、文字変数ではなく、じつは1バイト整数です。 で、'0'という文字は、言い換えれば0x30という整数なんです んで、'1'は、0x31。 そう考えてみれば理解できませんか
fumu7

2020/12/05 02:04

10進数は、0から9(10種類)の数字の列で表しますよね。0,1(2種類)の数字からなる列は2進数ですよ。unsigned charは、符号の無い(unsiguned)8ビットデータですから、10進数の0~255の値を表現できます。 "二進数","unsigned char"といった用語はWeb検索すれば解説しているページを容易に見つける事ができるはずです。そのぐらいの努力もせずに他人に頼るのは如何なものでしょうか。
grape_ll

2020/12/05 02:16

@y_waiwaiさん そうだったのですね.文字だとして見ていました.となると理解が進んだ気がします. あと,引っかかっているのは,私の中の理解では c1c2=00(binary)=0(decimal)ならばres=BASE_A というようになっていて,何の指定もなしにc1c2の文字列が2進数でそれを10進数に読み替えているということ,余分にシフト演算を行っていることです. ちなみになんですが,0xは16進数を表していて,'0'が0x30(decimalで48)であることに理由はあるのでしょうか.ただの順番というだけなのでしょうか.知識が乏しくて申し訳ございません.
grape_ll

2020/12/05 02:21

@fumu7さんへ 10進数や2進数の表現法自体を質問したつもりはありませんでした.それは一連の質問や会話の流れを見ていただければわかると思ってはいたのですが,少々言葉足らずだったようですね. 今回質問していたつもりでいたのは,指定もなしに2進数として受け取ってり10進数に変換しているのはなぜかということでした. unsigned charなども自分の中で文字としてわかっているものとしていたので調べなかったのですが,そもそも知識が間違っていたようです.
y_waiwai

2020/12/05 02:21

えーと、2進数10進数ってのは、数値の読み方が違うだけのはなしです それで数値が変わるわけじゃないです '0'という文字が0x30ってのは、文字コードで決まってますね。 ASCIIコードとか、UTF8ではそうなってます。 当然、文字コードが変わればそこらへんも変わります
y_waiwai

2020/12/05 02:22

16進で表現すれば、0x30、10進で表現すれば48、2進で表現すれば、00110000 ですね。 すべて同じ数値を表現してます
grape_ll

2020/12/05 02:28

読み方はこちらが指定しなくても勝手に調節してくれるということでしょうか. 今までの私の中では,デフォルトはdecimalで読み取って,何か命令をすると読み取り方を変えることが出来るのではないかと思っていました. 文字コードで決まっているのですね.理解いたしました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問