2017-01-26 4 views
0

空のプロジェクト。コード:floatにキャストするときに非常に大きな値を生成するarc4random_uniform

int i = 0; 
while (i < 8) { 
    float amount = 100-arc4random_uniform(200); 
    NSLog(@"amount: %f", amount); 
    i++; 
} 

ログイン:

amount: 21.000000 
amount: 90.000000 
amount: 79.000000 
amount: 4294967296.000000 
amount: 39.000000 
amount: 4294967296.000000 
amount: 81.000000 
amount: 4294967296.000000 

4294967296.000000は100 - ran(200)(擬似コード)の範囲外で明らかに

私はfloatとしてamountを宣言し、代わりにintこれを使用しない場合起こらない。

ここでは何が起こっていますか?

+4

arc4randomは符号なし整数を返します。減算を行う前に、(符号付きの)整数またはdoubleにキャストします。 – Rob

+0

@Robありがとう!何かが署名されているかどうかを知るための直感的な方法はありませんか、それとも私はドキュメントをチェックするだけですか?私は正式なコードトレーニングを受けておらず、ソースコードを読んで私が知っていることすべてを学んだだけなので、まだ署名付きと署名なしの違いは分かりません。私はそれが数字の前にある*記号*と関係していると仮定しています(または、「署名されていない」ためにそこに欠けています)。 –

+1

標準の32ビットの 'int'は-2,147,483,648と2,147,483,647の間の値を表すことができますが、' unsigned int 'は0と4,294,967,295の間の値しか表現できません(すなわち、2が32のべき乗から1を引いた値)。したがって、符号なしのint値0から1を引くと、-1を表すことができないので、4,294,967,295にラップします。知っている方法については、左に「クイックヘルプ」パネルを開いたままにすると、メソッドが返すタイプを確認するのがはるかに簡単になります。そして悲しいことですが、それは単に開発者であるあなたの責任で、メソッドの署名が正しいことを確認するだけです。 – Rob

答えて

1

@robが指摘しているように、arc4random_uniformは、32ビットの符号なし整数型(uint32_t)を返します。つまり、ゼロ以上の数値、負ではありません。したがってコンパイラは式100-arc4random_uniform(200)を評価し、結果も符号なしの数になることを期待します。

例コードの結果が100より大きい場合、100-arc4random_uniform(200)は、負の数を表すことのできないデータ型に負の数が割り当てられるため、予期しない結果になります。

@robが署名した数(この場合はfloat)にarc4random_uniformの結果をキャスト、示唆するようにあなたは、あなたが署名したことにより、数字を扱うことにしたいコンパイラに指示することができます

float amount = 100 - (float)arc4random_uniform(200); 

...または式が符号付きの数値を明示的に符号付きの数値にすることによって表現する必要があることを示すことによって表現されます:

float amount = 100.0f - arc4random_uniform(200); 
関連する問題