Negative Number Modulo in Swift

Negative number modulo in swift

The Swift remainder operator % computes the remainder of
the integer division:

a % b = a - (a/b) * b

where / is the truncating integer division. In your case

(-1) % 3 = (-1) - ((-1)/3) * 3 = (-1) - 0 * 3 = -1

So the remainder has always the same sign as the dividend (unless
the remainder is zero).

This is the same definition as required e.g. in the C99 standard,
see for example
Does either ANSI C or ISO C specify what -5 % 10 should be?. See also
Wikipedia: Modulo operation for an overview
how this is handled in different programming languages.

A "true" modulus function could be defined in Swift like this:

func mod(_ a: Int, _ n: Int) -> Int {
precondition(n > 0, "modulus must be positive")
let r = a % n
return r >= 0 ? r : r + n
}

print(mod(-1, 3)) // 2

Swift Double.remainder(dividingBy:) returning negative value

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

Understanding Remainder operator

From the same Basic Operators page that you link to:

The remainder operator (a % b) works out how many multiples of b will fit inside a and returns the value that is left over (known as the remainder).

Specifically for 1 % 5:

5 doesn't fit in 1, so it fits 0 times.

This means that 1 can be described as

1 = (5 * multiplier) + remainder

Since the multiplier is 0, the remainder is 1

1 = (5 * 0) + remainder
1 = remainder

If we instead look at 6 % 5 the remainder is also 1. This is because 5 fit in 6 one time:

6 = (5 * multiplier) + remainder
6 = (5 * 1) + remainder
6-5 = remainder
1 = remainder

Swift: Adding negative numbers

Check out Canvas diagnostics:

Swift.Float16:3:31: note: found this candidate
prefix public static func - (x: Float16) -> Float16
^
Swift.Float:2:31: note: found this candidate
prefix public static func - (x: Float) -> Float
^
Swift.Double:2:31: note: found this candidate
prefix public static func - (x: Double) -> Double
^
Swift.Float80:2:31: note: found this candidate
prefix public static func - (x: Float80) -> Float80

and tell Xcode which type you wanna use:

e.g.

Text(String(-Int(50) + 5))

or

Text(String(-50.0 + 5))

Arithmetic operator on negative numbers in Swift

-8 is less than -7, therefore your code should be:

if zPositionOfBowlingBall < -7 { 
// Do something here
}

if you want the value to be greater than 7 regardless of the sign you can use absolute value.

abs(<#value#>)

How do I use negative numbers in a range in Swift?

In the context of a switch case, a ... b is a "closed interval" and the start
must be less or equal to the end of the interval. Also a plus or minus sign must be
separated from ... by a space (or the number enclosed in parentheses), so both

case -10000...(-10):
case -10000 ... -10:

work.

case <= -10: can be written in Swift
using a "where clause":

case let x where x <= -10:

Starting with Swift 4 this can be written as a “one-sided range expression”:

case ...(-10):

Iterate Array and Count Changes from Negative to Positive (and vice versa)

Note: The exact logic about which pairs to count is subject to change, because I'm not exactly sure what you're looking for yet. It should be simple enough to make the proper changes as necessary.

Firstly, I'd clarify what kinds of transitions we're looking for. I'll be looking at transitions from negative numbers (less than 0), to non-negative numbers (0 and all positives). I'll simplify this with the following extension:

extension Integer {
var isNonNegative: Bool { return !isNegative }
var isNegative: Bool { return self < 0 }
}

In cases like this, where you're trying to iterate pairs of a Sequence, zip(_:_:) comes in really handy.

let array = [1, 2, 3, 4, -1, -1, -2, -3, 1, 2, 3, -1, -2]
let pairs = zip(array, array.dropFirst(1))
print(Array(pairs))

That results in these pairs:

[(1, 2), (2, 3), (3, 4), (4, -1), (-1, -1), (-1, -2), (-2, -3), (-3, 1), (1, 2), (2, 3), (3, -1), (-1, -2)]

From here, it's a matter of just counting the number of pairs in which the first element (.0) is negative, and the second element (.1) is positive. Like so:

let numRisingEdges = pairs.reduce(0) { count, pair in
if pair.0.isNegative && pair.1.isNonNegative { return count + 1 }
else { return count }
}

print(numRisingEdges) // => 1


Related Topics



Leave a reply



Submit