double のセットの因数を見つけようとしているので、まずそれらを整数に変換し、% を使用して除数を見つけます。
オプション1
私が抱えている問題は、ループで変換が発生したときに、特に次の関数を呼び出すと、いくつかの情報が失われることです。
func factors(number: Double) -> [Double] {
var result = [Double]()
var divisor = 0.1
let temporaryIncreasedNumber = Int(number) * 10
while number > divisor {
let theNewDivisor = divisor * 10
print("\(divisor) * \(10) = \(theNewDivisor) for \(divisor), \(temporaryIncreasedNumber) % \(Int(theNewDivisor)) is \(temporaryIncreasedNumber % Int(theNewDivisor))")
if temporaryIncreasedNumber % Int(theNewDivisor) == 0 {
//print ("dividing \(temporaryIncreasedNumber) by \(theNewDivisor) for \(divisor)")
result.append(divisor);
}
divisor += 0.1
}
return result
}
20の場合、次のようになります。
factors(number: 20.0))
たとえば、出力を見ると:
1.1 * 10 = 11.0 for 1.1, 200 % 10 is 0
どういうわけか、操作を行うと200 % Int(1.1 * 10)
、Int(1.1 * 10)
が 11 ではなく 10 を返します。理由がわかりません。もちろん、これはの検証に合格しますがA % B == 0
、そうすべきではありません。200 % 11 = 2
プレイグラウンドで手動で次のことを行いましたが、これはうまく機能し、次の結果が得られました200 % 11 = 2
let myX = 20.0
let myY = 1.1
let myCalc = Int(myX * 10.0) % Int(myY * 10.0)
let myCalc2 = 200 % 11
オプション 2
あるいは、単純に double のみを操作しても、一貫性のない値が得られます。コードを単純化すると、次のようになります。
func factors(number: Double) -> [Double] {
var result = [Double]()
var divisor = 0.1
while number > divisor {
let whole = (number/divisor).rounded(.towardZero)
print ("reminder of \(number) by \(divisor) = \((number/divisor) - whole)")
if (number/divisor) - whole == 0.0 {
result.append(divisor);
}
divisor = divisor + 0.1
}
return result
}
factors(number: 20.0)
何が問題なのかを確認できるように、切り捨てリマインダーを明示的に使用していないことに注意してください。
次の操作を見ると、予期しない結果が得られます。
reminder of 20.0 by 0.8 = 3.5527136788005e-15
しかし、プレイグラウンドで次のことを手動で行うと:
let test = (20.0/0.8) - (20.0/0.8).rounded(.towardZero)
結果は0!
while ループで動作が異なるのはなぜですか? 私のコードに何か問題がありますか?