2011-09-15 3 views
0

これは、メモリ割り当ての問題や配列の範囲外に出たときのようなアドレス指定の誤りなどのために、変数がランダムに数値を変更する前に私に起こっていました。狂ったように、なぜ私の変数が変わっていますか?

編集:私はこのループを実行した後、それは突然0に設定された後、「指数」は、ループ内288に等しいことを決定した理由はわかりませんので、しかし、私は、配列、またはポインタまたはアドレスを使用していませんよ。それは具体的に突破することを決めます:0x80800000

これは、一つの試験に壊れない、我々はいくつかのテストケース通じ​​た反復処理し、「テスト」クライアント、それは再びこれを呼び出すたびに、関数が再び呼び出された値がに等しくなるように設定する必要があり、それぞれの時間を持って自分の元の値。

/* 
* float_i2f - Return bit-level equivalent of expression (float) x 
* Result is returned as unsigned int, but 
* it is to be interpreted as the bit-level representation of a 
* single-precision floating point values. 
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while 
* Max ops: 30 
* Rating: 4 
*/ 
unsigned float_i2f(int x) { 
    int sign= 0; 
    int a=0; 
    int exponent=0; 
    int crash_test=0; 
    int exp=0; 
    int fraction=0; 
    int counter=0; 

    if (x == 0) return 0; 
    if (!(x^(0x01 << 31))) 
    { 
     return 0xCF << 24; 
    } 
    if (x>>31) 
    { 
     sign = 0xFF << 31; 
     x = (~x) + 1; 
    } 
    else 
    { 
     sign = 0x00; 
    } 
    //printf(" After : %x ", x); 

    a = 1; 
    exponent = 0; 
    crash_test = 0; 
    while ((a*2) <= x) 
    { 
     if (a == 0) a =1; 
     if (a == 1) crash_test = exponent; 
     /* 
     if(exponent == 288) 
     {exponent =0; 
      counter ++; 
      if(counter <=2) 
      printf("WENT OVERBOARD WTF %d ORIGINAL %d", a, crash_test); 
     } 
     */ 
     if (exponent > 300) break; 

     exponent ++; 
     a *= 2; 
    } 

    exp = (exponent + 0x7F) << 23; 
    fraction = (~(((0x01)<< 31) >> 7)) & (x << (25 - (exponent + 1))); 
    return sign | exp | fraction; 
} 
+1

私はそれを読むことができないので、コードをデバッグする途中で 'cout <<'の進捗を追加したいと思います。 – Blender

+2

このエラーは最小限の例ですか? – Beta

+2

288回反復した後、それは*正確に*等しいとなるでしょう... –

答えて

2

デバッガまたはIDEを使用しては、指数の値に主張/時計/ブレークポイントを設定する(例えば​​

そのfloat_i2f()がで呼び出されたxの問題の値は何でしたか?すべてのx、またはいくつかの範囲で指数が爆発したのですか?

(x = 0x80800000と言っていましたか?指数で時計を設定して、その値のデバッガでステップしましたか? 0x807FFFFFを確認してくださいrks、など?)

+0

これに追加すると、突然何も起こりません。反復可能なエラーであれば、同じことを間違った時間にしています。コードがどこで壊れているかを確認するために何が起こったのかを記録したり監視したりする必要があります。 – madmik3

+0

@ madmik3それはまさに私が彼に言ったことです:)もっと情報が必要です。 – smci

+0

基本的に私が言っていることは、yes x = 0x80800000で、Visual Studioでテストしようとしています。以前はgdbを使っていましたが、先生はテストケースプログラムを教えてくれました。 – oorosco

0

Visual Studioで自分で試したところ、「10」の入力をしても問題ありませんでした。

Q:失敗した入力値「x」を教えてください。

Q:どのコンパイラを使用していますか?どのプラットフォームを実行していますか?

+1

exponent ++; – madmik3

+0

私たちはgccを使用していますが、私たちはUNIXで "make"してからテストクライアントを実行します。テストクライアントは、私が間違っているかどうかを教えてくれます。それはテスト0x80800000でそれがうんざりしている、私はそれが0に設定され、指数がいくつかの神の予見された理由のために288に設定されるので、私はprogressignの不可能に絞り込んだ – oorosco

+0

コードをステップ実行するgdbを検討する。 http://www.unknownroad.com/rtfm/gdbtut/gdbuse.html – madmik3

0

whileループの最後に指数をインクリメントする行があります。

while((a*2) <= x) 
{ 
    if(a == 0) a =1; 
    if(a == 1) crash_test = exponent; 
    /* 

    if(exponent == 288) 
    { 
     exponent =0; 
     counter ++; 
     if(counter <=2) 
     printf("WENT OVERBOARD WTF %d ORIGINAL %d", a, crash_test); 
    } 
    */ 

    if(exponent > 300) break; 

    exponent ++; 
    a *= 2; 

} 
0

最適化には無駄な試行が多数ありましたが、コードを読みやすくするために削除しました。また、私は<stdint.h>タイプを適切に使用しました。

あり、ループにa *= 2に整数オーバーフローを署名したが、主な問題は、定数と魔法の数字の奇妙な計算の欠如でした。定数はすべての名前を付ける必要がありますので

これはまだ、例示的なものではなく、これは確実に動作しているようです。

#include <stdio.h> 
#include <stdint.h> 

uint32_t float_i2f(int32_t x) { 
    uint32_t sign= 0; 
    uint32_t exponent=0; 
    uint32_t fraction=0; 

    if (x == 0) return 0; 
    if (x == 0x80000000) 
    { 
     return 0xCF000000u; 
    } 
    if (x < 0) 
    { 
     sign = 0x80000000u; 
     x = - x; 
    } 
    else 
    { 
     sign = 0; 
    } 

    /* Count order of magnitude, this will be excessive by 1. */ 
    for (exponent = 1; (1u << exponent) <= x; ++ exponent) ; 

    if (exponent < 24) { 
     fraction = 0x007FFFFF & (x << 24 - exponent); /* strip leading 1-bit */ 
    } else { 
     fraction = 0x007FFFFF & (x >> exponent - 24); 
    } 
    exponent = (exponent + 0x7E) << 23; 
    return sign | exponent | fraction; 
} 
+0

奇妙なフォーマットがクラスに必要であり、そうでないものがあります。私は直接8ビット以上の定数を作ることはできませんし、私が考える条件のために "<"演算子を使うこともできません。 – oorosco

+0

それに取り組んで、それはA値をオーバーフローしている可能性があります、私はその場合のチェック条件を入れなければならないようです。 – oorosco

+0

8ビット以上の定数を作成できません。このクラスで何を教えているのか忘れることを忘れてください。このコードには多くのひどい慣行があります。 – Potatoswatter

0

変数exponentは何も神秘的なことをしていません。あなたはループのたびにexponentをインクリメントしていますので、最終的に好きな番号にヒットします。実際の質問は、ループが終了すると思わないときにループが終了しない理由です。

ループ条件はaに依存します。ループが繰り返されるにつれて、連続した値aを印刷してみてください。 aが1073741824に達した後に面白いことが起こったことに気づいていますか?あなたのクラスで整数オーバーフローについて聞いたことがありますか?

0

ちょうど「」負になる場合ハンドル(またはそれを、それは彼の最初の場所のint負になることはありませんので、あなたの入力を検証)、あなたは罰金:)

0

aオーバーフローしなければなりません。 a*2==0の場合a==1<<31ですので、毎回exponent%32==0,a==0となり、exponent==300までループします。

は、同様に他のいくつかの問題があります。

あなたfraction計算がexponent>=24時にオフになっています。負の左シフトは自動的に正の右シフトに変わりません。

部分を生成するマスクもやや間違っています。先頭ビットは常に1であると仮定し、仮数はわずか23ビットであるので、X < 2^23のための画分がなければならないれる。

fraction = (~(((0x01)<< 31) >> 8)) & (x << (24 - (exponent + 1))); 

ループabs(x)>=1<<31(及び付随的にもたらす場合exponentが失敗計算しますあなたが適切に丸めなければ、精密な喪失)。暗黙のうちに1を考慮するループがここではより良いでしょう。

関連する問題