2016-04-09 11 views
0

私はこの式を持っています。それはObjective-Cです。同じ式がObjective-CとSwiftで異なる値を返します

CGFloat x1 = self.frame.size.width/2 + ((self.frame.size.width - self.borderWidth * 2 - self.graduationOffset)/2) * cos((6 * i) * (M_PI/180) - (M_PI/2)); 

各変数/プロパティの値は次のとおりです。それらはすべてタイプCGFloatです。

self.frame.size.width = 200

self.borderWidth = 3

self.graduationOffset = 10

この式全体が60回実行するループです。 0からi開始の値と上記のコード例では60まで上昇するが、それはx1の値がある0

ました。

このようにこの表現をSwiftに変換しました。

let x1 = Double(frame.size.width/2 + ((frame.size.width - borderWidth * 2 - graduationOffset)/2)) * cos(Double((6 * i)) * (M_PI/180) - (M_PI/2)) 

変数に同じ値を渡す。私が得た結果は1.17566092718146e-14です。

私はそれを分解し、値を別々に調べてこれを理解しようとしました。しかしそれはもっと混乱を招いただけです。私は最終結果として0を得たので!

CGFloat a = self.frame.size.width/2 + ((self.frame.size.width - self.borderWidth * 2 - self.graduationOffset)/2); 
NSLog(@"%f", a); // 192.000000 
CGFloat b = cos((6 * i) * (M_PI/180) - (M_PI/2)); 
NSLog(@"%f", b); // 0.000000 
CGFloat c = a * b; 
NSLog(@"%f", c); // 0.000000 

私はSwiftでも同じことを試みましたが、結果は異なりました。

let a = Double(frame.size.width/2 + ((frame.size.width - borderWidth * 2 - graduationOffset)/2)) 
print(a) // 192.0 
let b = cos(Double((6 * i)) * (M_PI/180) - (M_PI/2)) 
print(b) // 6.12323399573677e-17 
let c = a * b 
print(c) // 1.17566092718146e-14 

私はこの一日中行ってきましたが、このすべてを理解することはできません。表現が評価される方法は、Objective-CとSwiftの違いがあると思いますか?私は本当に助けに感謝します。

+1

['NSLog' _rounds_6小数点までの出力](http://stackoverflow.com/questions/11410791/rounding-a-float-number-in-objective-c)、' print(..)格納された値を出力します。 '.... e-14'は古典的な浮動小数点精度の問題です(浮動小数点精度に関する多数のQ&Aのいずれかを検索するため)。この値は、本質的には「0」ですが、丸められていない場合は、すべての非精度の狂気を表示します。浮動小数点数の場合、等価テストや等価なテスト( 'b> 0?'など)を行わないようにしてください。 – dfri

+1

最初のステートメントとステートメントのブレークダウン*は同じではありません。最初のものでは、 'cos(...) 'を乗じた後、幅の半分を加えます。分割されたものでは、幅の半分を追加してから、「cos(...)」を乗じて – Hamish

+1

という誤解を招くタイトル「同じ表現」で下降します。これはリンゴ&オレンジではありません。デバッガを見るのではなく、2つの異なるロギングメカニズムを使って比較しています。そして、あなたは 'CGFloat'と' Double'の2つの異なるタイプを使用しています(32ビットデバイスと64ビットデバイスのどちらを比較しても言及されていません)。 – nhgrif

答えて

2

のは、3つの部分にあなたのObj-Cのコードを分割してみましょう:

CGFloat x1 = frameWidth/2 + ((frameWidth - borderWidth * 2 - graduationOffset)/2) * cos((6 * i) * (M_PI/180) - (M_PI/2)); 

CGFloat part1 = frameWidth/2; 
CGFloat part2 = ((frameWidth - borderWidth * 2 - graduationOffset)/2); 
CGFloat part3 = cos((6 * i) * (M_PI/180) - (M_PI/2)); 

あなたのObj-Cのバージョンでは、(私はあなたが*+に優先を持っていることを知っている確信している)でのご追加Double(...)キャストながらresult = part1 + (part2 * part3)をやっていますSwiftバージョンは式をresult = (part1 + part2) * part3に変換します。 part3i = 0の場合は0なので、結果は明らかです。

+3

@Isuruあなたのロジックを複数の行に分割するだけでなく、エラーを却下するだけでなく、コードをより読みやすく保守しやすくすることができます。コンパクトコード*純粋に*コンパクトコードのためにはまれなことです。 – Hamish

関連する問題