[swift-evolution] SE-0170: NSNumber bridging and Numeric types

Xiaodi Wu xiaodi.wu at gmail.com
Wed Apr 19 17:23:13 CDT 2017


On Wed, Apr 19, 2017 at 3:19 PM, Martin R <martinr448 at gmail.com> wrote:

> On 19. Apr 2017, at 01:48, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> So, as I understand it, `Float.init(exactly: Double.pi) == nil`. I would
> expect NSNumber to behave similarly (a notion with which Martin disagrees,
> I guess). I don't see a test that shows whether NSNumber behaves or does
> not behave in that way.
>
>
> At present they behave differently:
>
>     print(Float(exactly: Double.pi) as Any)
>     // nil
>     print(Float(exactly: NSNumber(value: Double.pi)) as Any)
>     // Optional(3.14159274)
>
> I realize that identical behavior would be logical and least surprising.
> My only concern was about cases like
>
>     let num = ... // some NSNumber from a JSON deserialization
>     let fval = Float(exactly: num)
>
> where one cannot know how the number is represented internally and what
> precision it needs. But then one could use the truncating conversion or
> `.floatValue` instead.
>

JSON numbers are double-precision floating point, unless I'm
misunderstanding something. If someone writes `Float(exactly:
valueParsedFromJSON)`, surely, that can only mean that they *really,
really* prefer nil over an imprecise value. I can see no other reason to
insist on using both Float and .init(exactly:).


>
> On Tue, Apr 18, 2017 at 11:43 AM, Philippe Hausler <phausler at apple.com>
> wrote:
>
>>
>> On Apr 18, 2017, at 9:22 AM, Stephen Canon <scanon at apple.com> wrote:
>>
>>
>> On Apr 18, 2017, at 12:17 PM, Joe Groff <jgroff at apple.com> wrote:
>>
>>
>> On Apr 17, 2017, at 5:56 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> It seems Float.init(exactly: NSNumber) has not been updated to behave
>> similarly?
>>
>> I would have to say, I would naively expect "exactly" to behave exactly
>> as it says, exactly. I don't think it should be a synonym for
>> Float(Double(exactly:)).
>> On Mon, Apr 17, 2017 at 19:24 Philippe Hausler via swift-evolution <
>> swift-evolution at swift.org> wrote:
>> I posted my branch and fixed up the Double case to account for your
>> concerns (with a few inspired unit tests to validate)
>>
>> https://github.com/phausler/swift/tree/safe_nsnumber
>>
>> There is a builtin assumption here though: it does presume that the
>> swift’s representation of Double and Float are IEEE compliant. However that
>> is a fairly reasonable assumption in the tests.
>>
>>
>>
>
> Even with the updated code at https://github.com/phausler/swift/tree/safe_
> nsnumber
>
>     print(Double(exactly: NSNumber(value: Int64(9000000000000000001))) as
> Any)
>     // Optional(9e+18)
>
> still succeeds, however the reason seems to be an error in the
> `init(exactly value: someIntegerType)` inititializers of Float/Double, I
> have submitted a bug report: https://bugs.swift.org/browse/SR-4634.
>
>
> (+Steve Canon) What is the behavior of Float.init(exactly: Double)?
>> NSNumber's behavior would ideally be consistent with that.
>>
>>
>> The implementation is essentially just:
>>
>> self.init(other)
>> guard Double(self) == other else {
>> return nil
>> }
>>
>> i.e. if the result is not equal to the source when round-tripped back to
>> double (which is always exact), the result is nil.
>>
>> – Steve
>>
>>
>> Pretty much the same trick inside of CFNumber/NSNumber
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170419/505f48a1/attachment.html>


More information about the swift-evolution mailing list