Skip to content

Commit

Permalink
Fix for ULong modulus operator
Browse files Browse the repository at this point in the history
The division-by-2 to use signed primitives means that the remainder can
be 0<=x%y<2y instead of 0<=x%y<y. This change makes it behave the same
way as the division operator, handling the two cases where the top bit
(0x8000000000000000) is set separately and, if not, then adjusting the
calculated remainder to ensure it's in range. This relies upon the fact
that (x%2y)%y == (x%y).
  • Loading branch information
rmw42 committed May 25, 2018
1 parent 7616cfd commit dcc1030
Showing 1 changed file with 25 additions and 33 deletions.
58 changes: 25 additions & 33 deletions src/main/scala/passera/unsigned/ULong.scala
Expand Up @@ -93,46 +93,38 @@ case class ULong(override val longValue: Long) extends AnyVal with Unsigned[ULon
val n = rep
val d = x.rep

if (true) return {
if (d < 0) {
if (this < x)
ULong(0l)
else
ULong(1l)
}
else {
val q = ((n >>> 1) / d) << 1
val r = n - q * d
if (ULong(r) >= x)
ULong(q+1)
else
ULong(q)
}
if (d < 0) {
if (this < x)
ULong(0l)
else
ULong(1l)
} else {
val q = ((n >>> 1) / d) << 1
val r = n - q * d
if (ULong(r) >= x)
ULong(q+1)
else
ULong(q)
}

val t = d >> 63
val n1 = n & ~t
val a = n1 >>> 1
val b = a / d
val q0 = b << 1
val r = n - q0 * d
val q = q0 + (if (ULong(r) >= x) 1l else 0l)
ULong(q.toLong)
}

def %(x: ULong): ULong = {
val n = rep
val d = x.rep


val t = d >> 63
val n1 = n & ~t
val a = n1 >>> 1
val b = a / d
val q0 = b << 1
val r = n - q0 * d
// val q = q0 + (if (ULong(r) >= ULong(d)) 1 else 0)
ULong(r.toLong)
if (d < 0) {
if (this < x)
ULong(n)
else
ULong(n - d)
} else {
val q = ((n >>> 1) / d) << 1
val r = n - q * d
if (ULong(r) >= x)
ULong(r - d)
else
ULong(r)
}
}

override def toString =
Expand Down

0 comments on commit dcc1030

Please sign in to comment.