A + B
を出力する興味深いCコードに出会いましたが、それを理解するのに苦労しています。
A B
ここで、A
、B
は、単一スペースで区切られた0
と10
の間の整数です。
main( n )
{
gets( &n );
printf("%d", n % 85 - 43);
}
これは短いコーディングを目的としており、警告を気にしないでください。
gets( &n )
は、n
の下位3バイトに、A、スペース、およびBのASCII値を格納します。たとえば、A = 3
およびB = 8
はn = 0x00382033
を生成します。与えられた条件は、n
のオーバーフローを防ぎます。しかし、n % 85 - 43
がA + B
を生成する方法がわかりません。
これらの数字はどうやって思いつきますか?
リトルエンディアンint(およびASCIIテキスト、8ビットバイト、およびコードが必要とする他のすべての仮定)を使用し、コード内の技術的に間違ったモダンCをすべて無視します。 、あなたの「これまでのところ私が理解していること」は正しい。
gets(&n)
は、A、スペース、BのASCII値をn
の最初の3バイトに格納します。また、ヌルターミネーターを4番目のバイトに格納します。これらのASCII値をn
のそれらのバイトに格納すると、n
が値B*256*256 + space*256 + A
を取ります。ここで、B
、space
、およびA
は対応するASCII値を表します。
256 mod 85は1なので、モジュラー演算の特性により、
(B*256*256 + space*256 + A) % 85 = (B + space + A) % 85
ちなみに、4バイトのビッグエンディアンのintでは、
(A*256*256*256 + space*256*256 + B*256) % 85 = (B + space + A) % 85
4バイトのintがあれば、エンディアンは関係ありません。 (より大きいまたはより小さいintが問題になる可能性があります。たとえば、8バイトのintでは、n
が設定しなかったgets
のバイトに何があるかを心配する必要があります。)
スペースはASCII 32で、数字のASCII値は48 +数字の値です。 a
およびb
を、入力された数字の数値(数字のASCII値ではなく)として定義すると、
(B + space + A) % 85 = (b + 48 + 32 + a + 48) % 85
= (a + b + 128) % 85
= (a + b + 43) % 85
(B + space + A) % 85 - 43 = (a + b + 43) % 85 - 43
= (a + b) % 85
= a + b
ここで、最後の2つの等価性は、a
およびb
が0から9までの値を取るという事実に依存しています。