Updated proposal: 
https://gist.github.com/karwa/273db66cd8a5fe2c388ccc7de9c4cf31 
<https://gist.github.com/karwa/273db66cd8a5fe2c388ccc7de9c4cf31>

Add integral rounding functions to FloatingPoint

Proposal: SE-NNNN <https://gist.github.com/karwa/NNNN-filename.md>
Author: Karl Wagner <https://github.com/karwa>
Status: Awaiting review 
<https://gist.github.com/karwa/273db66cd8a5fe2c388ccc7de9c4cf31#rationale>
Review manager: TBD
 
<https://gist.github.com/karwa/273db66cd8a5fe2c388ccc7de9c4cf31#introduction-motivation>Introduction,
 Motivation

The standard library lacks equivalents to the floor() and ceil() functions 
found in the standard libraries of most other languages. Currently, we need to 
import Darwin or Glibc in order to access the C standard library versions.

In general, rounding of floating-point numbers for predictable conversion in to 
integers is something we should provide natively.

Swift-evolution thread: [Proposal] Add floor() and ceiling() functions to 
FloatingPoint 
<https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160620/022146.html>
 
<https://gist.github.com/karwa/273db66cd8a5fe2c388ccc7de9c4cf31#proposed-solution>Proposed
 Solution

The proposed rounding API consists of a RoundingRule enum and new round and 
rounded methods on FloatingPoint

    /// Describes a rule for rounding to an integral value.
    enum RoundingRule {
        /// The result is the closest representable value greater than or equal 
to the source.
        case up
        /// The result is the closest representable value less than or equal to 
the source.
        case down
        /// The result is the closest representable value whose magnitude is 
less than or equal to that of the source.
        case towardZero
        /// The result is the closest representable value; if two values are 
equally close, the even one is chosen.
        case toNearestOrEven
        /// The result is the closest representable value; if two values are 
equally close, the one with greater magnitude is chosen.
        case toNearestOrGreatest
    }

protocol FloatingPoint {

    ...

    /// Returns a rounded representation of `self`, according to the specified 
rounding rule.
    func rounded(_ rule: RoundingRule = toNearestOrGreatest) -> Self

    /// Mutating form of `rounded`
    mutating func round(_ rule: RoundingRule = toNearestOrGreatest)
}
Calls such as rounded(.up) or rounded(.down) are equivalent to C standard 
library ceil() and floor() functions.

(4.4).rounded() == 4.0
(4.5).rounded() == 5.0
(4.0).rounded(.up) == 4.0
(4.0).rounded(.down) == 4.0
 
<https://gist.github.com/karwa/273db66cd8a5fe2c388ccc7de9c4cf31#impact-on-existing-code>Impact
 on existing code

This change is additive, although we may consider suppressing the imported, 
global-level C functions, or perhaps automatically migrating them to the new 
instance-method calls.

 
<https://gist.github.com/karwa/273db66cd8a5fe2c388ccc7de9c4cf31#alternatives-considered>Alternatives
 considered

floor() and ceiling(). The mailing list discussion indicated more nuanced forms 
of rounding were desired, and that it would be nice to abandon these technical 
names for what is a pretty common operation.
floor() and ceil() or ceiling() are mathematical terms of art 
<http://mathworld.wolfram.com/CeilingFunction.html>. But most people who want 
to round a floating point are not mathematicians.
nextIntegralUp() and nextIntegralDown() are more descriptive, and perhaps a 
better fit with the rest of the FloatingPoint API, but possibly misleading as 
(4.0).nextIntegralUp() == 4.0

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to