Reputation: 22497
Having not much to do over the holidays, I finally got round to updating my maths library to use the FloatingPoint
protocol, and get rid of all the duplicate code. To my surprise, I got bitten pretty much straight away by literal numbers:
func uprightAngle1<T: FloatingPoint>(_ x: T) -> T {
if (x > 0.5 * T.pi) && (x < 1.5 * T.pi) { // *** ERROR HERE
// binary operator '*' cannot be applied to operands of type 'Double' and 'T'
return x - T.pi
} else {
return x
}
}
however, this works fine:
func uprightAngle2<T: FloatingPoint>(_ x: T) -> T {
if (x > T.pi / 2) && (x < 3 * T.pi / 2) { // All fine here
return x - T.pi
} else {
return x
}
}
Can anyone
A) explain why the compiler is inferring the type correctly with the integer literals, but not with the floating point literal,
B) show me the idiom to use when I can't use rationals as neither let half: T = 0.5
nor T(0.5)
compile...
Upvotes: 2
Views: 147
Reputation: 539825
The FloatingPoint
protocol inherits from ExpressibleByIntegerLiteral
via the inheritance chain
FloatingPoint - SignedNumeric - Numeric - ExpressibleByIntegerLiteral
and that is why the second function uprightAngle2
compiles: Values
of the type T
are created from the integer literals 2
and 3
.
The first function uprightAngle1
does not compile because
the FloatingPoint
protocol does not inherit from ExpressibleByFloatLiteral
, i.e. values of type T
can not
be created from a floating point literal like 1.5
.
Possible solutions:
Create rational values as let half: T = 1/2
. (Not let half = T(1/2)
,
that would truncate the division result before creating the T
value.)
Replace FloatingPoint
by BinaryFloatingPoint
(which inherits
from ExpressibleByFloatLiteral
).
For more information about the design of the floating point protocols see SE-0067 Enhanced Floating Point Protocols.
The floating point types in the Swift Standard Library (Double
, Float
, CGFloat
, Float80
) as well as
CGFloat
from the Core Graphics framework all conform to the
BinaryFloatingPoint
protocol, so this protocol is "sufficiently
generic" for many applications.
Upvotes: 3