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'
}
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
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.
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.
It's not impossible, but it would kinda suck, and we wouldn't want people to do it.
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