3
let num = 32.0
Double(num).remainder(dividingBy: 12.0)

I'm getting -4?..instead of 8.0...it's subtracting 12.0 from 8.0

how do i fix this?

Sulthan
  • 128,090
  • 22
  • 218
  • 270
caa5042
  • 166
  • 3
  • 16
  • 1
    Unrelated but `Double(...` is redundant. Swift infers a floating point literal as `Double` by default. – vadian Sep 24 '18 at 20:24
  • If we want to know the remainder of 32 divided by 12, why aren't we using Ints and `%` here? Unless you have a very good reason to use Double (a reason that is not at all evident from the example), don't. – matt Sep 24 '18 at 20:33
  • 1
    Related: [truncatingRemainder vs remainder in Swift](https://stackoverflow.com/q/42724234/1187415) – Martin R Sep 24 '18 at 20:40

2 Answers2

9

Please, read the documentation carefully:

For two finite values x and y, the remainder r of dividing x by y satisfies x == y * q + r, where q is the integer nearest to x / y. If x / y is exactly halfway between two integers, q is chosen to be even. Note that q is not x / y computed in floating-point arithmetic, and that q may not be representable in any available integer type.

(emphasis mine)

You want to use truncatingRemainder(dividingBy:) instead:

let num = 32.0
let value = Double(num)
    .truncatingRemainder(dividingBy: 12)
print(value) // 8
Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • Interesting sidenote, if you write `Double(num) % 12`, there is an error in Xcode saying that `%` is not available and you should use `truncatingRemainder` instead. – Sulthan Sep 24 '18 at 20:14
  • @matt I meant that Xcode will actually tell you what method to use. – Sulthan Sep 24 '18 at 20:20
  • 1
    Ah, I see. Okay, but we don't know what the OP's intentions are. So far it's just weird that we're not converting to Int in the first place... :) – matt Sep 24 '18 at 20:32
  • From the docs, it says "...where q is the **integer** nearest to x / y." And then it says "q may not be representable in any integer type." That leaves me confused. – Duncan C Sep 25 '18 at 01:13
  • @DuncanC Double can be bigger than any possible integer. – matt Sep 25 '18 at 03:34
2

remainder(dividingBy:)is not the modulus function.

In real division 32.0/12.0 = 2.666666.... The remainder(dividingBy:) function defines the nearest integer to that result as q: in this case 3. So we write:

32.O = q * 12 + r

With q being an integer, and r a Double.

32.0 = 3 * 12.0 + r ⇒ r = - 4.0

The remainder r, as defined by this function, is -4.0.

ielyamani
  • 17,807
  • 10
  • 55
  • 90