Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

truncatingRemainder vs remainder in Swift

Tags:

swift

Swift's substitutes for the % symbol for floating point numbers:


func truncatingRemainder(dividingBy other: Self) -> Self 

Returns the remainder of this value divided by the given value using truncating division.


func remainder(dividingBy other: Self) -> Self 

Returns the remainder of this value divided by the given value.


The documentation didn't seem terribly clear. What's the practical difference between them, and when should each be used in preference to the other? Thanks.

like image 437
DenverCoder9 Avatar asked Mar 10 '17 17:03

DenverCoder9


2 Answers

truncatingRemainder computes the remainder of the "truncating division", and remainder computes the remainder of the "rounding division".

Example (from the API reference):

let x = 8.625
let y = 0.75

Truncating division and remainder:

let q1 = (x/y).rounded(.towardZero)
let r1 = x.truncatingRemainder(dividingBy: y)

print(q1, r1)      // 11.0 0.375
print(q1 * y + r1) // 8.625

Rounding division and remainder:

let q2 = (x/y).rounded(.toNearestOrEven)
let r2 = x.remainder(dividingBy: y)

print(q2, r2)      // 12.0 -0.375
print(q2 * y + r2) // 8.625

So in any case, the remainder rem of a division x by y is

rem = x - quot * y

where quot is "a rounded quotient" of the division x by y.

For truncatingRemainder, quot is the quotient rounded towards zero, and for remainder, quot is the quotient rounded towards the nearest integer.

The result of truncatingRemainder has always the same sign as the dividend, this need not be the case for remainder.

If both x and y are exactly representable as an integer then the result of

x.truncatingRemainder(dividingBy: y)

is the same as

Int(x) % Int(y)

with the integer remainder operator %.

like image 150
Martin R Avatar answered Sep 28 '22 03:09

Martin R


This looks like a job for...playgrounds!

let thing: Float = 8126.84652
let truncating = thing.truncatingRemainder(dividingBy: 10) // value is 6.84668, analog to %
let nonTruncating = thing.remainder(dividingBy: 10) // -3.15332

As you can see, the plain remainder is allowed to go negative, (or rather, subtracts until the value is <=0) whereas the truncating remainder will remain positive. (stops when the value is >=0)

like image 27
GetSwifty Avatar answered Sep 28 '22 04:09

GetSwifty