Skip to main content

DIVIDE

Divide the left operand by the right operand as signed integers to calculate a quotient and optional remainder.

OpcodeBytesCyclesFormExample
$a5329divide i:_, {s_byte}divide i:4, 123
$a7329divide i:_, i:_divide i:4, i:8
$dc429divide i:_, {s_byte}, remainder i:_divide i:4, 123, remainder i:8
$de429divide i:_, i:_, remainder i:_divide i:4, i:8, remainder i:12
Condition flagOutput
zero (ZF)If the quotient is zero, this flag is 1; otherwise it is 0.
negative (NF)If the quotient is negative, this flag is 1; otherwise it is 0.
overflow (OF)If the quotient cannot be correctly represented, this flag is 1; otherwise it is 0.
carry (CF)This flag is always 0.

Notes

  • Terminology: If we write a / b = q, a is called the dividend, b is the divisor, and q is the quotient. If the division is not exact, the remainder will be nonzero.

  • For example, divide i:4, i:8, remainder i:12 divides i:4 (the dividend) by i:8 (the divisor), storing the quotient back into i:4. The remainder is stored in i:12.

  • The remainder's register will always be assigned after the quotient's register. This allows a modulus expression such as x <- x %% 123 to be compiled as divide i:4, 123, remainder i:4 without need for a temporary register to discard the quotient.

  • If the divisor is zero, then the quotient result and remainder result will both be zero, and OF will be set to 1.

  • If -2147483648 is divided by -1, then the quotient result will be -2147483648, the remainder result will be 0, and OF is set to 1.

  • For these overflow cases, you can use the fail if overflow instruction to trap incorrect arithmetic results.

  • The with euclid mode does not affect these overflow cases.

  • This instruction performs signed division only. An unsigned form could be added, but aside from problems involving data sizes beyond this machine's limits, the cases that genuinely require unsigned division are already advanced enough to implement it by combining signed divide and shift.

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 never a negative 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 quotientTruncated remainder
17 / 5 = 317 % 5 = 2
-17 / 5 = -3-17 % 5 = -2
17 / -5 = -317 % -5 = 2
-17 / -5 = 3-17 % -5 = -2
Euclidean quotientEuclidean remainder
17 // 5 = 317 %% 5 = 2
-17 // 5 = -4-17 %% 5 = 3
17 // -5 = -317 %% -5 = 2
-17 // -5 = 4-17 %% -5 = 3