モジュラスを使用したC加算


81

印刷する興味深いCコードに出くわしましたが、A + B理解するのに苦労しています。

入力フォーマット:

どこAB間の整数である010単一のスペースで区切られています。

コード:

これは短いコーディングを目的としていました。警告を気にしないでください。

私がこれまでに理解していること:

gets( &n )A、スペース、およびBのASCII値をの下位3バイトに格納しますn。たとえば、A = 3B = 8はを生成しn = 0x00382033ます。与えられた条件nはオーバーフローを防ぎます。しかし、私はどのようにn % 85 - 43収穫するのか理解していませんA + B

これらの数字はどのようにして思いついたのですか?


2
確かに興味をそそられます。
Havenard

12
ヒントは、85がバイナリの交互のビットであるということ01010101です。このアプローチを10101010170という数字で試してみると、同様の機能が得られますが、唯一の違い0 010000000、代わりに128という数字(2進数)を取得することです。同様の手法を使用して、0x55555555and 0xAAAAAAAA(0x55 = 85および0xAA = 170)などのマスクを使用してビットセット内のビット数をカウントするなど、ビット単位の演算で一連の最適化を実行します。これらの16進コードをグーグルで検索すると、興味深い記事がたくさん表示されます。
Havenard

うわー、私は85という数字でこれほどの深さを期待していませんでした。洞察に感謝します。
ウィリアムリー

1
私はあなたが0と9の間を意味すると思いますか?
パイプ

1
それは間違いなくiocccに値するものです。
dgnuff 2018

回答:


87

リトルエンディアンのint(およびASCIIテキスト、8ビットバイト、およびコードが必要とする他のすべての仮定)を使用し、コード内の技術的に間違った現代のCのものをすべて無視すると、「私が理解していることこれまでのところ」は正しいです。

gets(&n)A、スペース、およびBのASCII値をの最初の3バイトに格納しますn。また、ヌルターミネータを4番目のバイトに格納します。それらのバイトにそれらのASCII値を格納するnに結果n値をとるB*256*256 + space*256 + A場合、Bspace、及びA対応するASCII値を表します。

256 mod 85は1なので、モジュラー演算のプロパティにより、

ちなみに、4バイトのビッグエンディアンintを使用すると、

したがって、4バイトのintがある限り、エンディアンは重要ではありません。(intが大きいか小さいかが問題になる可能性があります。たとえば、8バイトのintの場合、そのバイトに何が設定されngetsいないかを心配する必要があります。)

スペースはASCII32であり、数字のASCII値は48+数字の値です。入力された数字の数値として(数字のASCII値ではなく)を定義するaと、次のbようになります。

ここで、最後の2つの同等性は、abが0から9までの値を取るという事実に依存しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.