I’m with Nevin on this one. Perhaps the easiest thing to do is to add something to the FloatLiteral type that lets you get it as a string if desired.
Didn’t we have a discussion a while back on how to make Integer Literals work with BigInt? Maybe there is an idea from that discussion that would help. Tl;dr: Literals shouldn’t be tied to a particular implementation of a single conforming type (though they can/should be optimized for common implementations). The issue here is that FloatLiteral is throwing out information which is given to it based on its underlying implementation. I view this as a bug. Thanks, Jon > On Jan 16, 2018, at 4:20 PM, Nevin Brackett-Rozinsky via swift-evolution > <swift-evolution@swift.org> wrote: > > On Tue, Jan 16, 2018 at 6:31 PM, Xiaodi Wu <xiaodi...@gmail.com > <mailto:xiaodi...@gmail.com>> wrote: > On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky > <nevin.brackettrozin...@gmail.com <mailto:nevin.brackettrozin...@gmail.com>> > wrote: > The thing that is “broken” here is generic programming. If I constrain > something to FloatingPoint, I cannot use a float literal in calculations with > it: > > func centimeters<T: FloatingPoint> (inches: T) -> T { > return 2.54 * inches // Error > } > > Why not constrain it to `BinaryFloatingPoint`? What other types are you > trying to use with this function? > > We should not ask nor expect people to constrain their generic algorithms to > BinaryFloatingPoint unless they are working with the radix. > > > so that eg. a Rational type could be used. And that gives a hint as to the > workaround: > > func centimeters<T: FloatingPoint> (inches: T) -> T { > return (254 / 100) * inches > } > > Yes, you *could* do that. > > And it seems I *will* be doing that, as long as such a workaround is > necessary. Though it does appear to have the unfortunate cost of an extra > division operation. > > > That only works for numbers which don’t overflow the integer literals though. > > Integer literals don't overflow until 2048 bits. The following compiles just > fine: > > func moles<T : FloatingPoint>(particles: T) -> T { > let N_A: T = 602_214_085_774_000_000_000_000 > return particles / N_A > } > > When I write that in a playground it shows N_A as 1.67866967797794e+18. > > (Also, you appear to have mistakenly concatenated the standard uncertainty in > the last 2 digits, “74”, onto the accepted value for the constant.) > > > If we want a really large or small value then we have to split it in pieces: > > func moles <T: FloatingPoint> (particles: T) -> T { > let avogadroNumber: T = 6_022_140_857 * 100_000_000_000_000 > return particles / avogadroNumber > } > > It would be much nicer to write “let avogadroNumber: T = 6.022140857e23”. > > You could write: > > func moles<T : FloatingPoint & LosslessStringConvertible>(particles: T) -> T { > let N_A = T("6.02214085774e+23")! > return particles / N_A > } > > …or I could write “T: FloatingPoint & ExpressibleByFloatLiteral”. I could > even make a typealias for that. But I shouldn’t have to. > > Nevin > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution