Десятичный с очень длинным числом - PullRequest
0 голосов
/ 24 августа 2018

Я ожидал, что Decimal обработает число как String, но вместо этого я воспроизвел небольшое округление во время тестирования.

let locale = Locale(identifier: "en_GB")
let price: String? = "1535132527181273627"
let decimal: Decimal? = price != nil ? Decimal(string: price!, locale: locale) : nil
XCTAssertEqual(decimal, 1535132527181273627.0)

Результат меня беспокоит:

XCTAssertEqualошибка: («Необязательно (1535132527181274000)») не равно («Необязательно (1535132527181273497.6)») -

Ответы [ 3 ]

0 голосов
/ 24 августа 2018

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

Решение заключается в сравнении Decimal.

XCTAssertEqual(price, Decimal(string:"1535132527181273627"))
0 голосов
/ 25 августа 2018

Это проблема дизайна компилятора Swift.Сообщалось, что это SR-3317 , но оно было закрыто как дубликат SR-920 .

Проблема заключается в том, что литерал 1535132527181273627.0 анализируется какDouble литерал (то есть с ограниченной точностью), даже если тип должен быть Decimal.Использование String для инициализации Decimal является единственным обходным решением на данный момент.

Решение состоит в том, чтобы перепроектировать встроенный протокол ExpressibleByFloatLiteral , чтобы учесть более длинные числа.

0 голосов
/ 24 августа 2018

Я попробовал ваш код, и результат был:

Ошибка XCTAssertEqual: ("Необязательно (1535132527181273627)") не равно ("Необязательно (1535132527181273497.6)")

с использованием Xcode 9.4.1 на MacBook Pro 2015

Мне кажется, проблема в том, что Double может обрабатывать только 15 знаков после запятой.Таким образом, число 1535132527181273627.0 не может быть представлено точно.Взгляните на Двойная точность - десятичные разряды

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