mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
86 lines
1.7 KiB
V
86 lines
1.7 KiB
V
module math
|
|
|
|
// DivResult[T] represents the result of an integer division (both quotient and remainder)
|
|
// See also https://en.wikipedia.org/wiki/Modulo
|
|
pub struct DivResult[T] {
|
|
pub mut:
|
|
quot T
|
|
rem T
|
|
}
|
|
|
|
// divide_truncated returns the truncated version of the result of dividing numer to denom
|
|
@[inline]
|
|
pub fn divide_truncated[T](numer T, denom T) DivResult[T] {
|
|
return DivResult[T]{
|
|
quot: numer / denom
|
|
rem: numer % denom
|
|
}
|
|
}
|
|
|
|
// divide_euclid returns the Euclidean version of the result of dividing numer to denom
|
|
@[inline]
|
|
pub fn divide_euclid[T](numer T, denom T) DivResult[T] {
|
|
mut q := numer / denom
|
|
mut r := numer % denom
|
|
if r < 0 {
|
|
if denom > 0 {
|
|
q = q - 1
|
|
r = r + denom
|
|
} else {
|
|
q = q + 1
|
|
r = r - denom
|
|
}
|
|
}
|
|
return DivResult[T]{
|
|
quot: q
|
|
rem: r
|
|
}
|
|
}
|
|
|
|
// divide_floored returns the floored version of the result of dividing numer to denom
|
|
@[inline]
|
|
pub fn divide_floored[T](numer T, denom T) DivResult[T] {
|
|
mut q := numer / denom
|
|
mut r := numer % denom
|
|
if (r > 0 && denom < 0) || (r < 0 && denom > 0) {
|
|
q = q - 1
|
|
r = r + denom
|
|
}
|
|
return DivResult[T]{
|
|
quot: q
|
|
rem: r
|
|
}
|
|
}
|
|
|
|
// modulo_truncated returns the truncated remainder of dividing numer to denom
|
|
@[inline]
|
|
pub fn modulo_truncated[T](numer T, denom T) T {
|
|
return numer % denom
|
|
}
|
|
|
|
// modulo_euclid returns the Euclidean remainder of dividing numer to denom
|
|
@[inline]
|
|
pub fn modulo_euclid[T](numer T, denom T) T {
|
|
mut r := numer % denom
|
|
return if r < 0 {
|
|
if denom > 0 {
|
|
r + denom
|
|
} else {
|
|
r - denom
|
|
}
|
|
} else {
|
|
r
|
|
}
|
|
}
|
|
|
|
// modulo_floored returns the floored remainder of dividing numer to denom
|
|
@[inline]
|
|
pub fn modulo_floored[T](numer T, denom T) T {
|
|
r := numer % denom
|
|
return if (r > 0 && denom < 0) || (r < 0 && denom > 0) {
|
|
r + denom
|
|
} else {
|
|
r
|
|
}
|
|
}
|