サンプル問題 科目B 問16

問16  次のプログラム中の [  ] に入れる正しい答えを,解答群の中から選べ。二つの [  ] には,同じ答えが入る。ここで,配列の要素番号は 1 から始まる。 

Unicode の符号位置を,UTF-8 の符号に変換するプログラムである。本問で数値の後ろに“(16)”と記載した場合は,その数値が 16 進数であることを表す。 

Unicode の各文字には,符号位置と呼ばれる整数値が与えられている。UTF-8 は,Unicode の文字を符号化する方式の一つであり,符号位置が 800(16) 以上 FFFF(16) 以下の文字は,次のように 3 バイトの値に符号化する。 

3 バイトの長さのビットパターンを 1110xxxx 10xxxxxx 10xxxxxx とする。ビットパターンの下線の付いた“x”の箇所に,符号位置を 2 進数で表した値を右詰めで格納し,余った“x”の箇所に,0 を格納する。この 3 バイトの値が UTF-8 の符号である。 

例えば ,ひ らが なの “ あ”の 符号 位置 であ る 3042(16)  を 2 進数で表 すと11000001000010  である。これを,上に示したビットパターンの“x”の箇所に右詰めで格納すると,1110xx11 10000001 10000010  となる。余った二つの“x”の箇所に 0を格納すると,“あ”の UTF-8 の符号  11100011 10000001 10000010  が得られる。 

関数 encode は,引数で渡された Unicode の符号位置を UTF-8 の符号に変換し,先頭から順に 1 バイトずつ要素に格納した整数型の配列を返す。encode には,引数として,800(16) 以上 FFFF(16) 以下の整数値だけが渡されるものとする。 

〔プログラム〕 

○整数型の配列: encode(整数型: codePoint) 

  /* utf8Bytesの初期値は,ビットパターンの“x”を全て0に置き換え, 

     8桁ごとに区切って,それぞれを2進数とみなしたときの値 */ 

  整数型の配列: utf8Bytes ← {224, 128, 128} 

  整数型: cp ← codePoint 

  整数型: i 

  for (i を utf8Bytesの要素数 から 1 まで 1 ずつ減らす) 

    utf8Bytes[i] ← utf8Bytes[i] + (cp ÷ [  ] の余り) 

    cp ← cp ÷ [  ] の商 

  endfor 

  return utf8Bytes 

解答群 

ア  ((4 - i) × 2)   イ  (2 の (4 - i)乗)  
ウ  (2 の i 乗)   エ  (i × 2)  
オ  2  カ  6  キ  16  ク  64  ケ  256 

出典:基本情報技術者試験 サンプル問題

この問題について

Unicode文字コードUTF-8エンコードする問題ですね。やっていることは簡単なのですが、問題の見た目と解答群の選択肢の多さで受験生を脅そうという作戦かも知れません。

6ビットずつ取り出すことを整数演算で実現するにはどうすれば良いか、について考える問題ですね。6ビットで表せる数は0~63なので、一番下の6ビットは64で割った余りで求まります。次に64で割った商を求めて、この一番下の6ビットを切り捨てます。

さらに言えば、このプログラムでは最上位も6ビットとして扱っていますが、入力が16ビットしかないので、本当は4ビットとして処理するのが正しいはずです。まあ、上位桁は自動的に0が拡張されて、そのビットは0になるので問題ないよね、ということだと思いますが。

答え

雑感

改めて考えてみると、算術演算でビットがどう変化するか、ということはそんなに自明ではない気がします。逆に私がこれをできる理由を考えてみると、ビット操作演算子のない言語Pascalで、ビット操作を行うプログラムを作る業務に長い間携わっていたことが大きい気がします。今から考えると、不思議な業務でした。