[swift-evolution] [Proposal draft] Enhanced floating-point protocols

Chris Lattner clattner at apple.com
Thu Apr 14 23:06:36 CDT 2016


This proposal looks really really great, let me know when you want to start the review process (or just submit a PR for the -evolution repo) and I’ll happily review manage it for you.

On Apr 14, 2016, at 4:55 PM, Stephen Canon via swift-evolution <swift-evolution at swift.org> wrote:
> Provide basic constants (analogues of C's DBL_MAX, etc.)
Nice, have you considered adding pi/e and other common constants?  I’d really really like to see use of M_PI go away… :-)

> 
> /// SignedArithmetic protocol will only be conformed to by signed numbers,
> /// otherwise it would be possible to negate an unsigned value.
> ///
> /// The only method of this protocol has the default implementation in an
> /// extension, that uses a parameterless initializer and subtraction.
> public protocol SignedArithmetic : Arithmetic {
>   func negate() -> Self
Should this be negated / negate?  negate() seems like an in-place mutating version.

> /// A floating-point type that provides most of the IEEE 754 basic (clause 5)
Dumb Q, but is it “IEEE 754” or “IEEE-754”?


> /// operations.  The base, precision, and exponent range are not fixed in
> /// any way by this protocol, but it enforces the basic requirements of
> /// any IEEE 754 floating-point type.
> ///
> /// The BinaryFloatingPoint protocol refines these requirements and provides
> /// some additional useful operations as well.
> public protocol FloatingPoint: SignedArithmetic, Comparable {
> 
>   static var ulp: Self { get }
>   var ulp: Self { get }
Swift supports instance and type members with the same names, but this is controversial, leads to confusion, and may go away in the future.  It would be great to avoid this in your design.


> 
> 
>   //  TODO: strictly speaking a bit and a bool are slightly different
>   //  concepts.  Is another name more appropriate for this property?
>   //  `isNegative` is incorrect because of -0 and NaN.  `isSignMinus` might
>   //  be acceptable, but isn't great.  `signBit` is the IEEE 754 name.
>   var signBit: Bool { get }
I think you have this right, by calling it a bit and typing it as a Bool -using a Bool to represent a specific bit from Self seems right. 


>   /// The significand satisfies:
>   ///
>   /// ~~~
>   /// self = (signBit ? -1 : 1) * significand * radix**exponent
** isn’t a defined swift operator, it would be nice to change the comment to use something a swift programmer would recognize.


>   /// ~~~
>   ///
>   /// If radix is 2 (the most common case), then for finite non-zero numbers
>   /// `1 <= significand` and `significand < 2`.  For other values of `x`,
>   /// `x.significand` is defined as follows:
>   ///
>   /// - If `x` is zero, then `x.significand` is 0.0.
>   /// - If `x` is infinity, then `x.significand` is 1.0.
>   /// - If `x` is NaN, then `x.significand` is NaN.
...
>   var significand: Self { get }
I’m certainly not a floating point guru, but I would have expected significant to be of type RawSignificand, and thought that the significant of a nan would return its payload.  Does this approach make sense?

… later: I see that you have this on the binary FP type, so I assume there is a good reason for this :-)

>   /// Because of these properties, this initializer implements the IEEE 754
>   /// `scaleB` operation.
>   init(signBit: Bool, exponent: Int, significand: Self)
Stylistic question, but why list the initializers after members?


> 
>   /// Mutating form of square root.
>   mutating func formSquareRoot( )
extra space in the parens?


> 
>   /// Fused multiply-add, accumulating the product of `lhs` and `rhs` to `self`.
>   mutating func addProduct(lhs: Self, _ rhs: Self)
Stylistic, but it is easier to read with the mutating next to the non-mutating pairs.

>   /// True if and only if `self` is subnormal.
>   ///
>   /// A subnormal number does not use the full precision available to normal
>   /// numbers of the same format.  Zero is not a subnormal number.
>   var isSubnormal: Bool { get }
I’m used to this being called a “Denormal”, but I suspect that “subnormal” is the actually right name?  Maybe it would be useful to mention the “frequently known as denormal” in the comment, like you did with mantissa earlier.

> Impact on existing code
> 
> The % operator is no longer available for FloatingPoint types. We don't believe that it was widely used correctly, and the operation is still available via the formTruncatingRemainder method for people who need it.
> 
Also worth mentioning that this operator is not supported in popular languages like C either.

-Chris


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160414/04c82aa1/attachment.html>


More information about the swift-evolution mailing list