DIVIDE
Divide the left operand by the right operand to calculate a quotient and optional remainder.
| Opcode | Bytes | Cycles | Form | Example |
|---|---|---|---|---|
| $a5 | 3 | 29 | divide i:_, {s_byte} | divide i:4, 123 |
| $a7 | 3 | 29 | divide i:_, i:_ | divide i:4, i:8 |
| $dc | 4 | 29 | divide i:_, {s_byte}, remainder i:_ | divide i:4, 123, remainder i:8 |
| $de | 4 | 29 | divide i:_, i:_, remainder i:_ | divide i:4, i:8, remainder i:12 |
| Condition flag | Output |
|---|---|
| zero (ZF) | If the quotient is zero, this flag is 1; otherwise it is 0. |
| negative (NF) | If the signed quotient is a negative number, this flag is 1; otherwise it is 0. |
| overflow (OF) | If the divisor is zero, this flag is 1; otherwise it is 0. |
| carry (CF) | This flag is always 0. |
Notes
-
Terminology: If we write
a / b = q,ais called the dividend,bis the divisor, andqis the quotient. If the division is not exact, the remainder will be nonzero. -
For example,
divide i:4, i:8, remainder i:12dividesi:4(the dividend) byi:8(the divisor), storing the quotient back intoi:4. The remainder is stored ini:12. -
The remainder's register will always be assigned after the quotient's register. This allows a modulus expression such as
x <- x %% 123to be compiled asdivide i:4, 123, remainder i:4without need for a temporary register to discard the quotient. -
If the divisor is zero, the quotient and remainder will always be zero.
-
To trap division-by-zero, you can use the
fail if overflowinstruction.
Euclidean division
For historical reasons, most CPUs and programming languages such as C and Rust implement truncated division, where the remainder can be a negative number if the dividend is negative. Chombit's divide instruction performs truncated division by default. The Hybrix language's / and % operators are implemented this way.
Euclidean division ensures that the remainder is always a positive number. It is the most mathematically correct way to divide. This method is selected if a with euclid instruction immediately precedes the divide instruction. The Hybrix language's // and %% operators are implemented this way.
The table below illustrates the differences:
| Truncated quotient | Truncated remainder |
|---|---|
17 / 5 = 3 | 17 % 5 = 2 |
-17 / 5 = -3 | -17 % 5 = -2 |
17 / -5 = -3 | 17 % -5 = 2 |
-17 / -5 = 3 | -17 % -5 = -2 |
| Euclidean quotient | Euclidean remainder |
|---|---|
17 // 5 = 3 | 17 %% 5 = 2 |
-17 // 5 = -4 | -17 %% 5 = 3 |
17 // -5 = -3 | 17 %% -5 = 2 |
-17 // -5 = 4 | -17 %% -5 = 3 |