-6

決勝に向けて勉強する時が来たので、ループに関する詳細な情報をカバーする必要があります.私は現在、この質問に行き詰まっています.

int main(void) {
  int x = 0;
  int y = 0;
  while (y < 10) {
     x = 0;
     while (x != y) {// 
       x = x + 3; // how many times will we do this statement?
     }
     printf(“x is %d\n”, x);
     y = y + 1;
  }
}

基本的に、私は出力が何であるか、および前述のステートメントが実行された回数を確認しています。つまり、printf の出力はどのように見えるかということです。

これで私を助けてくれることを願っています。

どうもありがとう。

4

5 に答える 5

1

まず、質問の性質と、実装に依存しないオーバーフローラッピングに関する公式の(私が知っている)標準がないため、答えは正式には*不確定*です。

とは言うものの、非公式にそれの地獄のためにいくつかの数字をクランチさせましょう。これを32ビットintで計算しますが、64ビットの数値ははるかに印象的です。32^32も2^64も均等に割り切れないため、増分としての選択は非常に有利です(おそらく設計によるものですか?)。これにより、オーバーフローの連続性に最適になります。

物事を簡単にするいくつかのキー番号:

 2147483646 := (715827882 * 3)
-2147483647 := (2147483646 + 3) with overflow

Y = 0、X = 0であるため、反復ステートメントは実行されません。

  1. Y = 1、X = 0,3,6,9 ... 715827882の増分後、2147483646。次の増分はオーバーフローし、X=-2147483647になります。別の715827882は後で増分し、X=-1です。正の領域とX=2に戻るためのもう1つの増分。全体をもう一度繰り返し、X = 1、合計4 * 715827882 + 3、合計= 2863311531
  2. Y = 2、X = 0,3,6,9 ....上記の(1)を思い出してください。2*(715827882 + 1)の増分で、2、つまり1つのフルパスに到達しました。したがって、別の1431655766の実行、合計= 4294967297
  3. Y = 3、明らかな理由で、1回の反復でY = X=3。合計= 4294967298
  4. Y = 4、(1)を繰り返しますが、もう1つ増分を追加します。したがって、4 * 715827882 + 3 + 1回の反復、または2863311533。sum= 7158278830
  5. Y = 5、(2)を繰り返しますが、もう1つ増分を追加します。したがって、2 *(715827882 + 1)+ 1回の反復、または1431655767、合計= 8589934597
  6. Y = 6、(3)を繰り返しますが、もう1つ増分を追加します。したがって、1 + 1回の反復、合計= 8589934599
  7. Y = 7、(4)を繰り返しますが、もう1つ増分を追加します。したがって、4 * 715827882 + 3 + 1 + 1回の反復、または2863311533。sum= 11453246132
  8. Y = 8、(5)を繰り返しますが、もう1つ増分を追加します。したがって、2 *(715827882 + 1 + 1)+ 1回の反復、または1431655768、合計= 12884901900
  9. Y = 9、(6)を繰り返しますが、もう1つ増分を追加します。したがって、1 + 1 + 1回の反復、合計= 12884901903

1秒あたり3億回の反復をスピンできると仮定すると、完了するまでに約42.95秒かかります。

64ビット計算は思考の糧として残しておきます。ただし、実際の数値を熟考するために、64ビット整数空間での(val + = 3)インクリメントには、6148914691236517206の反復が必要です。上記の手順の中には、2回、1回、まったく実行しないものがあります。

32ビットのsignedint値を使用するようにテストプログラムを変更しました。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
    int32_t x = 0;
    int32_t y = 0;
    uint64_t sum = 0;

    while (y < 10)
    {
        x = 0;
        while (x != y)
        {
            x = x + 3; ++sum;
        }
        printf("x is %d; sum=%" PRId64 "\n", x, sum);
        y = y + 1;
    }
    return 0;
}

出力

x is 0; sum=0
x is 1; sum=2863311531
x is 2; sum=4294967297
x is 3; sum=4294967298
x is 4; sum=7158278830
x is 5; sum=8589934597
x is 6; sum=8589934599
x is 7; sum=11453246132
x is 8; sum=12884901900
x is 9; sum=12884901903
于 2012-12-01T11:02:41.837 に答える
1

この行は問題を引き起こします

 x = 0;
 while (x != y) {// 
   x = x + 3; // how many times will we do this statement?
 }

when y=1sincexは、最大整数値に達するまで増加し続けます (何らかのオーバーフロー ラッピングが発生しない限り、y と等しくなることはありません。これにより、無限ループが発生します)。

于 2012-12-01T08:54:43.400 に答える
0

それはひっかけ問題か、よく考えられていない問題です (または、最初に表示されるよりも高度な問題かもしれません)。

答えは、整数オーバーフローの特性に依存するため、決定できません。

なぜそうなるのかは、あなたにお任せします。最初に見えない場合は、ペンと紙で数回繰り返してみてください。さらに質問がある場合は、お気軽にお問い合わせください。:)

于 2012-12-01T08:51:21.590 に答える
0

while (x != y) {while ループが無限になる可能性があり、決して壊れることはありません。

例えば

  • 最初のループ x = 0、y = 0
  • 2nd while は実行されません。
  • 2 回目の反復 x = 0、y = 1
  • 2番目のwhileループで
    • 反復 1、x = 3
    • 反復 2、x = 6
    • そして、x が 1 になることは決してないので、それは続きます。
于 2012-12-01T08:53:17.520 に答える
0

あなたの内側のwhileは、次の理由で無限にループしていると思います:

x = 0 かつ y = 1 の場合、x = x + 3(x = 3) は常に != 1 なので、無限ループが発生します。

于 2012-12-01T08:55:57.550 に答える