Nicola Prada - 4 months ago 30
Swift Question

# Swift Remainder operator precision

I need to round stocks, indices and futures prices to the nearest tick. The first step is to look if the price is a multiple of the tick. Apple docs says "Unlike the remainder operator in C and Objective-C, Swift’s remainder operator can also operate on floating-point numbers".

If I write the following code in a playground or in a console app and I run it, I expect 0 as result but I get a remainder value equals to 0.00999999999999775:

``````var stringPrice = "17.66"
var price = Double(stringPrice)
var tickSize: Double = 0.01

let remainder = price! % ticksize
``````

This problem breaks my rounding function when using values such 17.66 as aPrice and 0.01 as aTickSize:

``````func roundPriceToNearestTick(Price aPrice: Double, TickSize a TickSize: Double)-> Double{
let remainder = aPrice % aTickSize
let shouldRoundUp = remainder >= aTickSize/2 ? true : false
let multiple = floor(aPrice/aTickSize)
let returnPrice = !shouldRoundUp ? aTickSize*multiple : aTickSize*multiple + aTickSize
return returnPrice
}
``````

What is the best way to fix this?

Following the comments about the broken floating point math and the need to avoid floats and doubles for all the operations concerning money I changed my code to perform the remainder operation using NSDecimalNumbers. This seems to solve the precision problem.

``````var stringPrice = "17.66"
var tickSizeDouble : Double = 0.01
var tickSizeDecimalNumber: NSDecimalNumber = 0.01

let behaviour = NSDecimalNumberHandler(roundingMode: NSRoundingMode.RoundDown,
scale: 0,
raiseOnExactness: false ,
raiseOnOverflow: false,
raiseOnUnderflow: false,
raiseOnDivideByZero: false )