ztn-zotan-swift-numerics/Sources/IntegerUtilities
Stephen Canon 31fe14d084 Remove stochastic rounding mode
It's a useful operation, but it deserves its own API to allow the use of a custom random source.
Also, the existing API blocks some constant-folding operations because the call to the system random source is an opaque optimization barrier, so removing it allows us to produce better codegen for the other rounding modes.

We're also bumping required Swift version to 5.9, and removing the executable test targets for log/log1p, as they're really only useful for development of those algorithms.
2025-04-10 10:39:51 -04:00
..
CMakeLists.txt First pass. 2023-04-26 16:43:50 -04:00
DivideWithRounding.swift Remove stochastic rounding mode 2025-04-10 10:39:51 -04:00
GCD.swift Adopt the Euclidean algorithm for GCD. 2024-04-19 20:54:57 -04:00
README.md Polish README.md 2023-04-28 13:58:37 -04:00
Rotate.swift Initial setup of IntegerUtilities module. 2021-08-25 15:36:24 -04:00
RoundingRule.swift Remove stochastic rounding mode 2025-04-10 10:39:51 -04:00
SaturatingArithmetic.swift Add new rounding modes: toNearestOr[Down,Up,Zero,Away] 2024-07-19 16:12:55 -04:00
ShiftWithRounding.swift Remove stochastic rounding mode 2025-04-10 10:39:51 -04:00

Integer Utilities

Note: This module is only present on main, and has not yet been stabilized and released in a tag.

Utilities defined for BinaryInteger

The following API are defined for all integer types:

  • The gcd(_:_:) free function implements the Greatest Common Divisor operation.

  • The shifted(rightBy:rounding:) method implements bitwise shift with rounding.

  • The divided(by:rounding:) method implements division with specified rounding. (See also SignedInteger.divided(by:rounding:), remainder(dividingBy:rounding:), and euclideanDivision(_:_:) below).

Utilities defined for SignedInteger

The following API are defined for signed integer types:

  • The divided(by:rounding:) method implementing division with specified rounding, returning both quotient and remainder. This requires a signed type because the remainder is not generally representable for unsigned types. This is a disfavored overload; by default, you will get only the quotient as the result:

    let p = 5.divided(by: 3, rounding: .up)      // p = 2
    let (q, r) = 5.divided(by: 3, rounding: .up) // q = 2, r = -1
    
  • The remainder(dividingBy:rounding:) method implementing the remainder operation; the rounding argument describes how to round the quotient, which is not returned. (The remainder is always exact, and hence is not rounded).

  • The euclideanDivision(_:_:) free function implements Euclidean division. In this operation, the remainder is chosen to always be non-negative. This does not correspond to any rounding rule on the quotient, which is why it uses a distinct API.

Utilities defined for FixedWidthInteger

  • The rotated(right:) and rotated(left:) methods implement bitwise rotation for signed and unsigned integer types. The count parameter may be any BinaryInteger type.

Saturating Arithmetic

The following saturating operations are defined as methods on FixedWidthInteger:

  • addingWithSaturation(_:)
  • subtractingWithSaturation(_:)
  • negatedWithSaturation(_:)
  • multipliedWithSaturation(by:)
  • shiftedWithSaturation(leftBy:rounding:)

These implement saturating arithmetic. They are an alternative to the usual +, -, and * operators, which trap if the result cannot be represented in the argument type, and &+, &-, &*, and <<, which wrap out-of-range results modulo 2ⁿ for some n. Instead these methods clamp the result to the representable range of the type:

let x: Int8 = 84
let y: Int8 = 100
let a = x + y                     // traps due to overflow
let b = x &+ y                    // wraps to -72
let c = x.addingWithSaturation(y) // saturates to 127

If you are using saturating arithmetic, you may also want to perform saturating conversions between integer types; this functionality is provided by the standard library via the init(clamping:) API.

Types

The RoundingRule enum is used with shift, division, and round operations to specify how to round their results to a representable value.