[swift-evolution] [Proposal] Add floor() and ceiling() functions to FloatingPoint

Saagar Jha saagarjha28 at gmail.com
Mon Jun 27 14:34:37 CDT 2016


Seems fine to me. One addition though: some sort of round(withPrecision:
Int)
On Mon, Jun 27, 2016 at 12:23 Stephen Canon via swift-evolution <
swift-evolution at swift.org> wrote:

>
> On Jun 27, 2016, at 12:34 PM, Karl <razielim at gmail.com> wrote:
>
>
> On 27 Jun 2016, at 16:23, Stephen Canon <scanon at apple.com> wrote:
>
>
> On Jun 25, 2016, at 05:06, Karl via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Proposal: https://gist.github.com/karwa/273db66cd8a5fe2c388ccc7de9c4cf31
>
>
> Karl, thanks for writing this up.  It should be extended to include not
> only floor( ) and ceiling( ), but also:
>
> /// Returns the integral value closest to `self` whose magnitude is not
> greater than that of `self`.
> func truncate( ) -> Self
>
> /// Returns the integral value closest to `self`.  If two integrers are
> equally close, the even one
> /// is returned.
> //  NOTE: The name of this function requires bike-shedding.  I’ve chosen a
> deliberately poor
> //  name as a straw-man.
> func roundToNearestTiesToEven( ) -> Self
>
> /// Returns the integral value closest to `self`.  If two integrers are
> equally close, the one with
> /// greater magnitude is returned.
> //  NOTE: The name of this function requires bike-shedding.  I’ve chosen a
> deliberately poor
> //  name as a straw-man.
> func roundToNearestTiesAway( ) -> Self
>
> and mutating versions of those.
>
>
> I was trying to add these, but working out the names of the mutating
> functions is difficult. How is truncate different to floor if it returns an
> integral value and can never round up?
>
>
> Perhaps for the other functions, we could have a general `round` function
> with a tiebreak-enum parameter (it would be great if we could embed enums
> in protocols, but I’m not sure if that’s even on the roadmap):
>
> enum FloatingPointRoundingStrategy {   // or something to that effect
>     case preferEven
>     case preferGreatest
> }
>
> func rounded(inTiebreak: FloatingPointRoundingStrategy) -> Self
>
> I think `(4.5).rounded(inTiebreak: .preferGreatest) == 5.0` looks quite
> nice.
>
>
> Yes, something along these lines might work, though
> `FloatingPointRoundingStrategy` isn’t quite right; after all,
> round-towards-infinity (aka ceiling) is also a rounding strategy.
>
> One option (which I don’t totally love, but which simplifies the API
> surface quite a bit, and avoids adding more formXXXX constructions) would
> be to fold all the rounding rules into a single member function (very
> strawman):
>
> /// 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 upwards
> /// The result is the closest representable value less than or equal to
> the source.
> case downwards
> /// 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 toNearestTiesToEven
> /// The result is the closest representable value; if two values are
> equally close, the one with greater magnitude is chosen.
> case toNearestTiesAway
> }
>
> /// Rounds to an integral value according to the specified rounding rule.
> mutating func round(_ rule: RoundingRule = toNearestTiesAway)
>
> func rounded(_ rule: RoundingRule = toNearestTiesAway) -> Self
>
> That gives us e.g.:
>
> let x = -2.5
> x.round(.upwards) // -2
> x.round(.downwards) // -3
> x.round(.towardZero) // -2
> x.round(.toNearestTiesToEven) // -2
> x.round() // -3
>
> We might also provide free functions that implement the most common
> operations under the familiar libc names (I realize that free-functions are
> not broadly considered “swifty”, but they may be appropriate here; we would
> effectively simply be moving these free functions from Darwin/Glibc into
> the stdlib, and making them available for all FloatingPoint types).
>
> func ceil<T: FloatingPoint>(_ x: T) -> T {
> return x.rounded(.upwards)
> }
>
> func floor<T: FloatingPoint>(_ x: T) -> T {
> return x.rounded(.downwards)
> }
>
> func trunc<T: FloatingPoint>(_ x: T) -> T {
> return x.rounded(.towardZero)
> }
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-- 
-Saagar Jha
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160627/e21cf8e9/attachment.html>


More information about the swift-evolution mailing list