div(other: Decimal, scale: int, mode: Rounding Mode = Rounding Mode.Half Even()) - > Result<Decimal, string>- Module
- std.
decimal - Receiver
- Decimal
- Minimum arity
- 2
- Maximum arity
- 3
Declaration and parameters
LinkAvailability
Included by default: Pending
Import std.decimal in language mode 5.21.
The current compiler selects std/decimal.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.
Source evidence
- compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1143 - compiler/crates/topaz_resolve/src/stdlib.rs at
b48527d0a174· 62 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1143 - compiler/crates/topaz_self_frontend/topaz/checker/builtin_signatures.tpz at
b48527d0a174· 479 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1296 - compiler/crates/topaz_value/src/value/members.rs at
b48527d0a174· 304 - compiler/crates/topaz_value/src/value/builtin_catalog.rs at
b48527d0a174· 1110
Receiver
Decimal
Parameter constraints
Decimal.div evaluates the exact quotient of its receiver and the divisor. For a nonzero divisor it rounds that quotient once to the requested decimal grid and returns Ok containing the normalized Decimal.
The requested scale and mode have the same meaning as in Decimal.round. Omitting the mode selects RoundingMode.HalfEven(). Input scales and coefficient sizes do not introduce another precision limit or an intermediate rounding step.
A nonterminating decimal quotient is rounded to the requested grid. A terminating quotient that is already on the grid remains exact. The canonical result scale can be smaller than the requested scale.
Division signs follow ordinary numeric division. All six rounding modes apply to the signed exact quotient, including negative ties and results that round to zero.
A zero divisor returns Err with the string Decimal.. This includes zero divided by zero and a divisor parsed from a negative zero spelling. This failure is a Result value and does not raise TPZ4002.
A zero dividend and a nonzero divisor return Ok containing zero for every valid requested scale. An internal sum of operand and requested scales must not turn a nonzero divisor into a division by zero error.
An invalid requested scale raises TPZ5001 during execution before the zero divisor is classified. The operation never replaces an invalid scale with zero or reports that scale error as a successful Result.
The receiver, divisor, scale and explicitly supplied mode expressions evaluate once in that order before their values are validated. The operation preserves both operands.
Related rule: Divide with an explicit result scaleResult
The declared result type is Result<Decimal, string>.
Effects
Failures
Result and effects
LinkRound the exact quotient once with the supplied mode and normalize the result. The default mode is HalfEven. Invalid scales raise TPZ5001 during execution before zero divisor classification.
Why
LinkAn explicit result grid gives a nonterminating quotient a defined finite result while Result keeps a zero divisor recoverable.
Resolved contracts
LinkRelated entries
LinkDivide with an explicit result scale
LinkDivide with an explicit result scale
Decimal.div evaluates the exact quotient of its receiver and the divisor. For a nonzero divisor it rounds that quotient once to the requested decimal grid and returns Ok containing the normalized Decimal.
The requested scale and mode have the same meaning as in Decimal.round. Omitting the mode selects RoundingMode.HalfEven(). Input scales and coefficient sizes do not introduce another precision limit or an intermediate rounding step.
A nonterminating decimal quotient is rounded to the requested grid. A terminating quotient that is already on the grid remains exact. The canonical result scale can be smaller than the requested scale.
Division signs follow ordinary numeric division. All six rounding modes apply to the signed exact quotient, including negative ties and results that round to zero.
A zero divisor returns Err with the string Decimal.. This includes zero divided by zero and a divisor parsed from a negative zero spelling. This failure is a Result value and does not raise TPZ4002.
A zero dividend and a nonzero divisor return Ok containing zero for every valid requested scale. An internal sum of operand and requested scales must not turn a nonzero divisor into a division by zero error.
An invalid requested scale raises TPZ5001 during execution before the zero divisor is classified. The operation never replaces an invalid scale with zero or reports that scale error as a successful Result.
The receiver, divisor, scale and explicitly supplied mode expressions evaluate once in that order before their values are validated. The operation preserves both operands.
Why
A division result needs an explicit decimal grid because a finite pair of decimals can have a nonterminating quotient. Rounding the exact quotient once avoids hidden precision loss. A recoverable zero divisor stays distinct from invalid configuration and from internal scale arithmetic.
Source evidence
- compiler/crates/topaz_value/src/value/decimal.rs at
693a4cb69c39· 167 - compiler/crates/topaz_value/src/value/builtins/bigint_decimal.rs at
693a4cb69c39· 217 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1916 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
b48527d0a174· 1319 -
topaz.stdlib.contract.decimal-divisionatworking-tree - topaz.decision.decimal-division.1 at
topaz.decisi
Distinguish exact and repeating quotients at the requested grid
Linkimport std.decimal { Decimal }import std.testimport std.iofunction show(result: Result<Decimal, string>) -> () {let value: Decimal = test.assertOk(result)io.writeLine("{value.toString()} {value.scale()}")}let one: Decimal = (1).toDecimal()let third: Result<Decimal, string> = one.div((3).toDecimal(), 6)let eighth: Result<Decimal, string> = one.div((8).toDecimal(), 2)let negativeTie: Result<Decimal, string> = (-1).toDecimal().div((8).toDecimal(), 2)let exact: Result<Decimal, string> = (100).toDecimal().div((4).toDecimal(), 4)let integerGrid: Result<Decimal, string> = (2).toDecimal().div((3).toDecimal(), 0)show(third)show(eighth)show(negativeTie)show(exact)show(integerGrid)
0.333333 6 0.12 2 -0.12 2 25 0 1 0
Expected result
Expected result
Execution completes. Exit code 0.
0.333333 60.12 2-0.12 225 01 0
Source evidence
- compiler/crates/topaz_value/src/value/decimal.rs at
693a4cb69c39· 167 - compiler/crates/topaz_value/src/value/builtins/bigint_decimal.rs at
693a4cb69c39· 217 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1916 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
b48527d0a174· 1319 -
topaz.stdlib.contract.decimal-divisionatworking-tree - topaz.decision.decimal-division.1 at
topaz.decisi
Apply every rounding mode to signed quotient ties
Linkimport std.decimal { Decimal, RoundingMode }import std.testimport std.iofunction read(text: string) -> Decimal {let parsed: Option<Decimal> = Decimal.parse(text)let value: Decimal = test.assertSome(parsed)return value}function quotient(text: string, mode: RoundingMode) -> string {let value: Decimal = read(text)let result: Result<Decimal, string> = value.div((2).toDecimal(), 0, mode)let rounded: Decimal = test.assertOk(result)return rounded.toString()}let modes: Array<RoundingMode> = [RoundingMode.Down(), RoundingMode.Up(), RoundingMode.TowardZero(), RoundingMode.AwayFromZero(), RoundingMode.HalfUp(), RoundingMode.HalfEven()]for mode in (modes) {let a = quotient("5", mode)let b = quotient("7", mode)let c = quotient("-5", mode)let d = quotient("-7", mode)io.writeLine("{a} {b} {c} {d}")}
2 3 -3 -4 3 4 -2 -3 2 3 -2 -3 3 4 -3 -4 3 4 -3 -4 2 4 -2 -4
Expected result
Expected result
Execution completes. Exit code 0.
2 3 -3 -43 4 -2 -32 3 -2 -33 4 -3 -43 4 -3 -42 4 -2 -4
Source evidence
- compiler/crates/topaz_value/src/value/decimal.rs at
693a4cb69c39· 167 - compiler/crates/topaz_value/src/value/builtins/bigint_decimal.rs at
693a4cb69c39· 217 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1916 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
b48527d0a174· 1319 -
topaz.stdlib.contract.decimal-divisionatworking-tree - topaz.decision.decimal-division.1 at
topaz.decisi
Return a recoverable error for every zero divisor
Linkimport std.decimal { Decimal }import std.testimport std.iofunction read(text: string) -> Decimal {let parsed: Option<Decimal> = Decimal.parse(text)let value: Decimal = test.assertSome(parsed)return value}let divisor: Decimal = read("-0.000")let numerators: Array<Decimal> = [(0).toDecimal(), (1).toDecimal()]for numerator in (numerators) {let result: Result<Decimal, string> = numerator.div(divisor, 2)match (result) {case Err(message) => io.writeLine(message)case Ok(_) => io.writeLine("accepted")}}io.writeLine(divisor.toString())
Decimal.div: division by zero Decimal.div: division by zero 0
Expected result
Expected result
Execution completes. Exit code 0.
Decimal.div: division by zeroDecimal.div: division by zero0
Source evidence
- compiler/crates/topaz_value/src/value/decimal.rs at
693a4cb69c39· 167 - compiler/crates/topaz_value/src/value/builtins/bigint_decimal.rs at
693a4cb69c39· 217 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1916 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
b48527d0a174· 1319 -
topaz.stdlib.contract.decimal-divisionatworking-tree - topaz.decision.decimal-division.1 at
topaz.decisi
Keep a zero quotient at the largest valid scale
Linkimport std.decimal { Decimal }import std.testimport std.iofunction read(text: string) -> Decimal {let parsed: Option<Decimal> = Decimal.parse(text)let value: Decimal = test.assertSome(parsed)return value}let divisor: Decimal = read("0.1")let result: Result<Decimal, string> = (0).toDecimal().div(divisor, 4294967295)match (result) {case Ok(value) => io.writeLine(value.toString())case Err(_) => io.writeLine("unexpected error")}
0
Expected result
Expected result
Execution completes. Exit code 0.
0
Source evidence
- compiler/crates/topaz_value/src/value/decimal.rs at
693a4cb69c39· 167 - compiler/crates/topaz_value/src/value/builtins/bigint_decimal.rs at
693a4cb69c39· 217 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1916 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
b48527d0a174· 1319 -
topaz.stdlib.contract.decimal-divisionatworking-tree - topaz.decision.decimal-division.1 at
topaz.decisi
Evaluate the receiver and division arguments once in order
Linkimport std.decimal { Decimal, RoundingMode }import std.testimport std.iofunction receiver() -> Decimal {io.writeLine("receiver")return (6).toDecimal()}function divisor() -> Decimal {io.writeLine("divisor")return (4).toDecimal()}function scale() -> int {io.writeLine("scale")return 1}function mode() -> RoundingMode {io.writeLine("mode")return RoundingMode.HalfEven()}let result: Result<Decimal, string> = receiver().div(divisor(), scale(), mode())let value: Decimal = test.assertOk(result)io.writeLine(value.toString())
receiver divisor scale mode 1.5
Expected result
Expected result
Execution completes. Exit code 0.
receiverdivisorscalemode1.5
Source evidence
- compiler/crates/topaz_value/src/value/decimal.rs at
693a4cb69c39· 167 - compiler/crates/topaz_value/src/value/builtins/bigint_decimal.rs at
693a4cb69c39· 217 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1916 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
b48527d0a174· 1319 -
topaz.stdlib.contract.decimal-divisionatworking-tree - topaz.decision.decimal-division.1 at
topaz.decisi
Reject an invalid scale before classifying a zero divisor
Linkimport std.decimal { Decimal }import std.iolet value: Decimal = (1).toDecimal()value.div((0).toDecimal(), -1)io.writeLine("after")
No stdout.
Expected result
Source evidence
- compiler/crates/topaz_value/src/value/decimal.rs at
693a4cb69c39· 167 - compiler/crates/topaz_value/src/value/builtins/bigint_decimal.rs at
693a4cb69c39· 217 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1916 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
b48527d0a174· 1319 -
topaz.stdlib.contract.decimal-divisionatworking-tree - topaz.decision.decimal-division.1 at
topaz.decisi
Reject an invalid scale before classifying a zero divisor
Linkimport std.decimal { Decimal }import std.iolet value: Decimal = (1).toDecimal()value.div((0).toDecimal(), 4294967296)io.writeLine("after")
No stdout.
Expected result
Source evidence
- compiler/crates/topaz_value/src/value/decimal.rs at
693a4cb69c39· 167 - compiler/crates/topaz_value/src/value/builtins/bigint_decimal.rs at
693a4cb69c39· 217 - compiler/crates/topaz_self_frontend/topaz/checker/members_capabilities.tpz at
b48527d0a174· 1916 - compiler/crates/topaz_self_frontend/topaz/checker/call_complete.tpz at
b48527d0a174· 1319 -
topaz.stdlib.contract.decimal-divisionatworking-tree - topaz.decision.decimal-division.1 at
topaz.decisi