-
Notifications
You must be signed in to change notification settings - Fork 3
Design notes
Notes on design and implementation choices.
While there is generally no contention among programming languages as far as the quotient and remainder of positive operands are concerned, they do disagree when it comes to the quotient and remainder of negative operands. Here's a quick overview and comparison with other programming languages.
Div
implements truncating division, that is,
- it is the same as the
/
operator in Vim script, C, Java, JavaScript, the Pythondecimal
module, Go, and Bash; - it is not the same as the
/
operator in Ruby, Python (//
), and Tcl, which implement floored division.
Similarly, Rem
- is the same as the
%
operator in Vim script, C, Java, JavaScript, the Pythondecimal
module, Go, Bash, and AWK; - it is also the same as
remainder
in Ruby,rem
in Clojure,rem
in Haskell, andRem
in Go's big integer library; - but it is not the same as
%
in Python, Ruby, Perl, and Tcl, which implement floored division.
For Div
, Rem
, and DivRem
the Java standard library class
java.math.BigInteger
is a close model in both name and behaviour: it
has divide
, remainder
, and divideAndRemainder
, which produce the
same results as the corresponding functions of magnum.vim.
The fact that DivRem
implements truncating division is simply a design
choice. If you need a different type of division you must implement it
yourself.
For example, here is an extension of magnum.vim that implements Euclidean division and modulus.
" Returns the pair [quotient, modulus] obtained by dividing x by y using
" Euclidean division.
function! DivMod(x, y) abort
let [l:q, l:r] = a:x.DivRem(a:y)
if !l:r.IsNegative()
return [l:q, l:r]
elseif a:y.IsPositive()
return [l:q.Sub(g:magnum#ONE), l:r.Add(a:y)]
else
return [l:q.Add(g:magnum#ONE), l:r.Sub(a:y)]
endif
endfunction
See Daan Leijen, 'Division and modulus for computer scientists'.