2017-02-04 47 views
5

Numaraları saf İngilizce sözcüklere dönüştürüyorum ve bazı garip durumlara rastladım: NSNumberFormatter tuhaf bir çıktıya sahiptir, istenen sonuçtan daha küçüktür ancak parametre olarak alınan sayı taşmaya neden olmaz.NSNumberFormatter.string (from:) maximum possible Değeri aşılırsa taşma - Taşma - Swift

Aşağıdaki kod var:

import Foundation 
var numberFormatter: NumberFormatter = NumberFormatter() 
numberFormatter.numberStyle = .spellOut 
var result: String? 
result = numberFormatter.string(from: 999999999999999999) 
print(result ?? "nil") 

ve bu 18014398509481984 < 999999999999999999 eşdeğer olan eighteen quadrillion fourteen trillion three hundred ninety-eight billion five hundred nine million four hundred eighty-one thousand nine hundred eighty-four yazdırır. 18014398509481984'dan kelimeleri almaya çalışırsam, beklenen sonuç, yukarıda açıklanan dizedir. soru daha yapmak için, İşte Int

içine saklanan zaman

tamsayı değişmezi 9999999999999999999 taşmaları Swift Sandbox Test: Ben 9999.. bir daha eklerseniz Ancak, mesajla çöküyor anlaşılabilir.


Benim asıl soru şudur: ilk denemede çıktısı varsayarsak: 180140398509481984numberFormatter.string(from:) için sınırın bir tür, neden Overflow sonuçlanmaz 999999999999999999 vermez, ama sadece birlikte (bu sınırı görüntüler ve 9999999999999999999 Fazladan bir 9) Taşma ile sonuçlanır? Bu Int64.max daha büyük olduğu için

+1

Garip. "180140398509481985" işlevini kullansanız bile, hecelendiğinde hala "180140398509481984" elde edersiniz. – rmaddy

+1

Bu da garip bir sınır. 2^57 ile 2^58 arasında. – rmaddy

+0

@rmaddy bu tam olarak ne soruyorum. Sadece bu işlevin bir sınırı mı, yoksa Int/NSNumber max değeriyle ilgili bir problem mi? –

cevap

4

9_999_999_999_999_999_999 (yani 0x7fffffffffffffff) 9_223_372_036_854_775_807 bir Int taşmasına neden olur. sayı biçimlendirici değeri 64 bit kayan nokta representions kaynaklanan bir böcek gibi şüpheli görünüyor, .spelledOut için 18_014_398_509_481_984 (yani, 2 , 0x40000000000000) dışarı sınırı neden ilişkin

. NSNumberFormatter ve NSNumber için kaynak ayrılmadan emin olamayız, ama bunu öneririm çünkü üstteki tavan, tesadüfen, 64-bit kayan nokta tipinin sadakatle yakalayabileceği en büyük tamsayı değerini tam olarak iki katına çıkarır.

+0

Ben farketmedim ... teşekkürler –

+1

Vakıf ve Çekirdek Vakfı açık kaynaklı.['CFNumberFormatterCreateStringWithNumber'] (https://github.com/apple/swift-corelibs-foundation/blob/173e9ea16cf1a0ed9b21cc11ea8a2d15b3f8dca9/CoreFoundation/Locale.subproj/CFNumberFormatter.c) işlevi bile," CFNumbers ile değerleri büyük imzasız 64-bit ints bunun aracılığıyla iyi hayatta kalmaz. Apple'ın bu problemi zaten biliyormuş gibi görün. –