配列のインデックスを計算するために、CGFloat
をint
にフロアまたはシーリングする必要があることがよくあります。
floorf(theCGFloat)
またはceilf(theCGFloat)
で永久に見られる問題は、浮動小数点の不正確さで問題が発生する可能性があることです。
つまり、CGFloat
が2.0f
であるが、内部的には1.999999999999f
またはそのようなものとして表される場合はどうでしょうか。私はfloorf
を実行し、再びfloatである1.0f
を取得します。それでも私はこの獣をintにキャストしなければならず、別の問題を引き起こす可能性があります。
2.0
のようなものが偶然に1
にフロアリングされず、2.0
のようなものが偶然に2
にシーリングされないように、float
をint
にフロアリングまたはシーリングするベストプラクティスはありますか?
あなたの質問にはいくつかの誤解があります。
cGFloatが2.0fであるが、内部的には1.999999999999fと表されている場合
起こり得ない; 2.0は、すべての合理的に小さい整数と同様に、浮動小数点で正確に表現されます。 CGFloat
が2.0f
、それは実際には2.0です。
2.0のようなものが誤って2に制限されることはありません
2.0の上限is 2;それはおそらく他に何でしょうか?
私があなたが本当に質問している質問は、「数学的にすべきが正確に2.0であるが、実際にはわずかに少ない不正確な結果を生成する計算を行うと仮定します。floor
その値にすると、2.0ではなく1.0になります。これを防ぐにはどうすればよいですか?」
これは実際には、「正しい」答えが1つもないかなり微妙な質問です。入力値をどのように計算しましたか?結果をどうしますか?
迅速な補足回答
floor
とceil
をCGFloat
と一緒に使用する方法を探してここに来た人のための補足的な回答としてこれを追加します(私がしたように)。
_var myCGFloat: CGFloat = 3.001
floor(myCGFloat) // 3.0
ceil(myCGFloat) // 4.0
_
Int
が必要な場合は、1にキャストできます。
_var myCGFloat: CGFloat = 3.001
Int(floor(myCGFloat)) // 3
Int(ceil(myCGFloat)) // 4
_
更新
C floor
関数とceil
関数を使用する必要がなくなりました。 Swift round()
と 丸め規則 を使用できます。
_var myCGFloat: CGFloat = 3.001
myCGFloat.round(.down) // 3.0
myCGFloat.round(.up) // 4.0
_
元の変数を変更したくない場合は、rounded()
を使用します。
注意事項
も参照してください
編集-この答えが正しくない理由のコメントを読んでください:)
float
をint
にキャストすると、暗黙的にfloorf
になります。つまり、_(int)5.9
_は_5
_になります。あなたがそれを気にしないなら、ただキャストしてください:)
切り上げたい場合はceilf
の結果をキャストするだけです-丸め後にキャストしてもエラーは発生しません(または、必要に応じてエラーを追加してからキャストします(つまり、 `(int)(5.9+ 1) 'は' 6 'です-切り上げと同じです)。
最も近い値に丸めるには、0.5を追加します-_(int)(5.9+0.5)
_は_6
_ですが、_(int)(5.4+0.5)
_は_5
_です。私はroundf(5.9)
を使用するだけですが:)