Кто-нибудь знает, почему это даже компилировать? - PullRequest
0 голосов
/ 27 февраля 2019

Существует множество различных инициализаторов типа Double, но любой должен, кроме String, в качестве параметра.

Почему эта компиляция (и возвращает значение!) ???

if let d = Double("0xabcdef10.abcdef10") {
    print(d)
}

itпечатает

2882400016.671111

импорт не требуется, пожалуйста, ребята, проверьте это с вашей средой ...

ОБНОВЛЕНИЕ Спасибо, ребята, моя проблема не в том, чтобы понять, какпредставляет значение Double в виде шестнадцатеричной строки.

Я путаюсь с несовместимой реализацией

protocol LosslessStringCovertible

 init?(_:) REQUIRED
 Instantiates an instance of the conforming type from a string representation.

 Declaration
 init?(_ description: String)

И Double, и Int соответствуют LosslessStringCovertible (Int косвенно, через соответствие FixedWidthInteger)

В начале я начал с

public func getValue<T: LosslessStringConvertible>(_ value: String)->T {
    guard let ret = T.init(value) else {
        // should never happen
        fatalError("failed to assign to \(T.self)")
    }
    return ret
}
// standart notation
let id: Int = getValue("15")
// hexadecimal notation
let ix: Int = getValue("0Xf") // Fatal error: failed to assign to Int

OK, это детали реализации, поэтому я решил реализовать его самостоятельно, который принимает строку с двоичной, октальной, шестнадцатеричной нотацией

затем я проделал то же самое для Double и, протестировав его, обнаружил, что когда я забыл импортировать свой LosslessStringConvertibleExt, мои тесты прошли для ожидаемого Double, где строка была шестнадцатеричнойв десятичной записи.

Спасибо LeoDabus за Ваш комментарий со ссылкой на документы, который я не нашел раньше (да, скорее всего, я ослеп, это спасло меня немногочасы: -)

Я прошу прощения у всех вас за «глупый» вопрос.

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Строка была интерпретирована как дробный гекс.Вот как рассчитывается десятичное значение:

| Hex Digit | Decimal Value | Base Multipler | Decimal Result            |
|-----------|---------------|----------------|---------------------------|
| a         | 10            | x 16 ^ 7       |  2,684,354,560.0000000000 |
| b         | 11            | x 16 ^ 6       |    184,549,376.0000000000 |
| c         | 12            | x 16 ^ 5       |     12,582,912.0000000000 |
| d         | 13            | x 16 ^ 4       |        851,968.0000000000 |
| e         | 14            | x 16 ^ 3       |         57,344.0000000000 |
| f         | 15            | x 16 ^ 2       |          3,840.0000000000 |
| 1         | 1             | x 16 ^ 1       |             16.0000000000 |
| 0         | 0             | x 16 ^ 0       |              0.0000000000 |
| .         |               |                |                           |
| a         | 10            | x 16 ^ -1      |              0.6250000000 |
| b         | 11            | x 16 ^ -2      |              0.0429687500 |
| c         | 12            | x 16 ^ -3      |              0.0029296875 |
| d         | 13            | x 16 ^ -4      |              0.0001983643 |
| e         | 14            | x 16 ^ -5      |              0.0000133514 |
| f         | 15            | x 16 ^ -6      |              0.0000008941 |
| 1         | 1             | x 16 ^ -7      |              0.0000000037 |
| 0         | 0             | x 16 ^ -8      |              0.0000000000 |
--------------------------------------------------------------------------
| Total     |               |                |  2,882,400,016.6711100000 |
0 голосов
/ 27 февраля 2019

Из документации о сбоях Double init:

Шестнадцатеричное значение содержит значение и 0X или 0x, за которым следует последовательность шестнадцатеричных цифр.Значение и может содержать десятичную точку.

let f = Double("0x1c.6") // f == 28.375

Таким образом, 0xabcdef10.abcdef10 интерпретируется как шестнадцатеричное число с учетом префикса 0x.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...