[swift-evolution] [Review] SE-0080: Failable Numeric Conversion Initializers

Matthew Johnson matthew at anandabits.com
Wed May 4 09:52:51 CDT 2016


> On May 3, 2016, at 11:26 PM, Gwendal Roué via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> The review of "SE-0080: Failable Numeric Conversion Initializers" begins now and runs through May 9. The proposal is available here:
>> 
>> 	https://github.com/apple/swift-evolution/blob/master/proposals/0080-failable-numeric-initializers.md
> 
> Hello,
> 
> I'm all for it, but I'd like a clarification about... the Integer / Floating point interface.
> 
> I once had to write a function that compares Int64 to Double for strict equality, with all the sweats that come whenever you deal with floating point representations and have to introduce two-complements representation of integers as a mandatory precondition:
> 
> 	/// Returns true if i and d hold exactly the same value, and if converting one
> 	/// type into the other does not lose any information.
> 	private func int64EqualDouble1(_ i: Int64, _ d: Double) -> Bool {
> 	    return (d >= Double(Int64.min))
> 	        && (d < Double(Int64.max))
> 	        && (round(d) == d)
> 	        && (i == Int64(d))
> 	}
> 
> As I understand well the proposal, I could write instead:
> 
> 	private func int64EqualDouble2(_ i: Int64, _ d: Double) -> Bool {
> 	    guard let j = Int64(exact: d) else { return false }
> 	    return i == j
> 	}
> 
> But I may be wrong!
> 
> The "without loss of information" in the proposal means that -0.0 (minus zero) would *not* be convertible to Int64 (which would lose the sign). And we'd get:
> 
> 	int64EqualDouble1(0, -0.0) // true
> 	int64EqualDouble2(0, -0.0) // false
> 
> No problem with that. To know if int64EqualDouble1 has a bug, or if int64EqualDouble2 should handle -0.0 explicitly, one needs to know how -0.0 should be handled.

This is a good example to consider.  I am not a numerics expert and hadn’t thought to consider -0.0.  Intuitively I would expect that to convert to 0 when converted to an integer type, however your are right that this is technically a loss of information about the sign bit.  

I am happy to defer to those with more numerics expertise than I have about what an implementation should do in this case.  I am also happy to defer to numerics experts about how to precisely define “loss of information” in general.  

As noted in the proposal, the primary use case I am concerned with is reading data from semi-structured sources such as JSON where there is only a single “number” type.  In these cases the value will be received as a Double but our model may specify an Int, Uint, Int8, etc.  Any implementation that allows for validating the conformance of a value to expectations of our model and extracting the valid value with the correct type will be sufficient for the use cases I can imagine.

> 
> So I think that the proposal should make it very clear how it wants to handle all the funny Float and Double values. Without such a clarification, as handy as they look like, those functions would remain surprising, which means very hard to use well, and we'll keep on sweating.

Are there any values other than -0.0 we need to worry about?  Clearly NaN, Infinity, and -Infinity cannot be represented by integer types and integer initializers would return nil when called with these floating point values.



> 
> Gwendal Roué
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list