> On Jun 27, 2016, at 12:34 PM, Karl <[email protected]> wrote:
>
>
>> On 27 Jun 2016, at 16:23, Stephen Canon <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>>
>>> On Jun 25, 2016, at 05:06, Karl via swift-evolution
>>> <[email protected] <mailto:[email protected]>> wrote:
>>>
>>>> Proposal: https://gist.github.com/karwa/273db66cd8a5fe2c388ccc7de9c4cf31
>>>> <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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution