のXcode 8.2.1、スウィフト3.彼らは(一見)ほとんどの些細なコードで予期しない問題を明らかにするときスウィフト二重に奇妙な負
import UIKit
extension Double {
/// Linear interpolation.
/// Converts a number in one range to its equivalent in another range.
func interpolate(from: ClosedRange<Int>, to: ClosedRange<Int>) -> Double {
let oldValue = self
let offset = Double(to.lowerBound - from.lowerBound)
let expansion = Double(to.upperBound - to.lowerBound)/Double(from.upperBound - from.lowerBound)
print("\nvalue", oldValue)
print("Sign", self.sign)
print("offset", offset)
print("expansion", expansion)
print("oldLowerbound", Double(from.lowerBound))
let newValue = (oldValue - Double(from.lowerBound)) * expansion + offset
return newValue
}
}
print(1.0.interpolate(from: 0...10, to: 50...70)) // Prints 52.0. Correct
print(-1.0.interpolate(from: 0...10, to: 50...70)) // Prints -52.0. Expected 48.0.
print((-1.0).interpolate(from: 0...10, to: 50...70)) // Prints 48. Correct.
ユニットテストは、自分自身のために支払う:
(上記のコードはiOSのプレイグラウンドで実行されます)
Double
を拡張する方法は、2番目のprint文を期待通りに機能させるためです(3番目のprint文のように大括弧を使用しないでください)。
答えていただきありがとうございます。私は評価の順序が問題の原因であることを知っていましたが、その周りに道があることを望んでいました。そうではないようです。 –
@ VinceO'Sullivan:Btw、あなたのコードにエラーがあります。それは 'let offset = Double(to.lowerBound)'でなければなりません。例として '0.0.interpolate(〜:5 ... 5、〜:-5 ... 5)'を試してみてください! –
あなたはそうです。私の "範囲"の範囲が常にゼロで始まったという事実は、そのエラーを隠していました。ありがとう。 –