Vince O&#39;Sullivan -4 years ago 132
Swift Question

# Swift doubly strange when negative

Xcode 8.2.1, Swift 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.
``````

Unit tests pay for themselves when they reveal unexpected problems in the most (seemingly) trivial code:

(The code above will run in an iOS playground.)

Is there a way to extend
`Double`
in order to get the second print statement to work as expected (without resorting to brackets as in the third print statement)?

It is a matter of evaluation order. Your second expression is evaluated as

``````-(1.0.interpolate(from: 0...10, to: 50...70)) // -52.0
``````

i.e. `interpolate()` is called on `1.0`, and the result negated.

You have to set explicit parentheses as in your third expression, so that `interpolate()` is called on `-1.0`:

``````(-1.0).interpolate(from: 0...10, to: 50...70) // 48.0.
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download