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 OVERFLOW instruction.
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 an 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 |