Is Double FloatingPoint?

Why doesn't this work? Is Double not FloatingPoint?

let val: Double = 1

func foo<T: FloatingPoint>() -> T {
    T(val) // Error: Cannot convert value of type 'Double' to expected argument type 'Int'
}

FloatingPoint has initializers from integers (docs), but no requirement that it can be initialized from another arbitrary FloatingPoint.

BinaryFloatingPoint does, however, have such an initializer: Apple Developer Documentation

1 Like

Interesting, thank you. What is the rationale for this behaviour that FloatingPoint can't be initialised from another FloatingPoint?

User-defined types can conform to FloatingPoint (or BinaryFloatingPoint, for that matter), but there’s no way that the standard library types could know how to initialize themselves from such an instance.

But that somehow possible with BinaryFloatingPoint, what's the difference here?

It can; it can use the protocol requirements.

If you take a look at what FloatingPoint provides, it's incredibly abstract. Some basic properties like isNaN, isFinite, basic maths operations and comparison, and the radix, exponent and significand. Importantly, the significand returns a value of type Self. So it's kind of hard to get the magnitude; you can calculate it, but it'll be the same type you started with, so it's not that helpful for type conversions.

BinaryFloatingPoint just has a lot more information, so you do a better job of interpreting which number its supposed to represent.

If you're looking for more nuanced design rationale, I don't know. "Reasons", I guess. But from a practical perspective looking at the protocols, I think it would be difficult/impossible to create a generic FloatingPoint-from-other-arbitary-FloatingPoint initializer. It's just not designed for that.

1 Like

According to @scanon, FloatingPoint also represents non-binary floating point formats. Though I’m not sure whether knowing a floating point format is binary makes it any easier to store its values using primitive stdlib types…

Correct, it is not possible to write an initializer that creates a floating-point value from a value of an arbitrary other floating-point type with the protocol’s available guarantees.

The initializer was originally a requirement of FloatingPoint and was revised to be moved down to BinaryFloatingPoint on account of its not being implementable with FloatingPoint APIs.

3 Likes

It's not impossible, but it would kinda suck, and we wouldn't want people to do it.

1 Like

Sure, for any particular concrete type I guess it’s possible but gross.

I was pretty certain when I wrote the default implementation that it wasn’t possible to write one for FloatingPoint-to-FloatingPoint conversion, but I also know that you have more insight on this :slight_smile: