-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
FrozenDueToAgeLanguageChangeSuggested changes to the Go languageSuggested changes to the Go languageProposalv2An incompatible library changeAn incompatible library change
Milestone
Description
This is a proposal for a (backward-compatible) language extension.
The notion of comma-ok expressions can be extended in a natural way to the 4 basic
arithmetic operations (+, -, *, /) such that a 2nd result value (traditionally the
"ok" value) provides the carry, borrow, overflow, and remainder value,
respectively.
Specifically (spec wording):
-----
A binary expression with one the four basic arithmetic operators may be used in an
assignment of initialization of the special form:
z, c = x op y
z, c := x op y
var z, c = x op y
var z, c T = x op y
The operator op must be one of +, -, *, or /. The value and type of z is the same as in
the single-result form. In the special form, the type of c is the same as the type of z,
and the value of c is defined as follows:
For +, -, and /, the value of c is (x op y) >> s with the operation carried out in
twice the precision of the types of the operands, and with s = operand type size in
bits. For /, the value of c is the remainder x%y.
In other words:
for +, c is the "carry" value (0 or 1)
for -, c is the "borrow" value (0 or -1)
for *, c is the "overflow" value
for /, c is the remainder
-----
The implementation is straight-forward since these c values tend to be computed anyway:
For +, and -, the value of c corresponds to the "carry/borrow bit" usually
computed always for these operations. The carry bit simply needs to be converted and
stored (between 1 to 3 machine instructions, depending on architecture, storage
location). Division operations usually leave the remainder in a register. Only
multiplication requires double-width arithmetic, and only if c is required.
Applications:
- Code that needs to check for integer overflow can be simplified. For unsigned ints,
the c value is the desired bit.
- Numeric conversions (from integer to decimal) require both / and % on the same
operands. Providing q, r := x/y is likely to run twice as fast w/o the need for the
compiler to detect that a % operation following a / is using the same operands.
- Some of the core routines required for arbitrary precision arithmetic can be written
in a straight-forward manner in Go and should achieve similar performance as
corresponding assembly code, without the need for fancy compiler optimizations.
Concrete example: If x, y, z represent fixed-size high precision unsigned integers (n*64
bits), + could be written as follows:
const n = 100
var x, y, z [n]uint64
// compute z = x + y
var c uint64
for i, x := range x {
z[i], c = x + y[i] + c
}
Without the special z, c = x + y form, analogous code written in c will be prohibitively
expensive compared to the respective assembly.dsnet, saintech, bcmills, rressi, ericlagergren and 6 more
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeLanguageChangeSuggested changes to the Go languageSuggested changes to the Go languageProposalv2An incompatible library changeAn incompatible library change