Преобразование Double в NSNumber в Swift Loses Accuracy

По некоторым причинам некоторые двойники в моем приложении Swift приносят мне проблемы при конвертации в NSNumber, а некоторые нет. Моему приложению нужно преобразовать двойные числа с двумя десятичными знаками (цены) в NSNumbers, чтобы их можно было хранить и извлекать с помощью Core Data. Например, несколько конкретных цен, таких как 79.99, будут оцениваться до 99.98999999999999, если они специально не форматируются с использованием метода doubleValue NSNumber.

Здесь selectedWarranty.price = 79.99, как показано в отладчике

// item.price: NSNumber? // selectedWarranty.price: Double? item.price = NSNumber(double: selectedWarranty.price!) 

Я запрограммировал некоторые операторы печати, чтобы показать, как выполняется преобразование

 Original double: 79.99 Converted to NSNumber: 79.98999999999999 .doubleValue Representation: 79.99 

Может ли кто-нибудь объяснить, есть ли причина, почему инициализатор не может наверняка сохранить 2 десятичных знака для каждого номера? Я действительно хотел бы хранить цены в Core Data, как они должны быть. Форматирование каждый раз, когда оно отображается, не очень удобно.

UPDATE : объект Converted Core Data для типа NSDecimalNumber через модель данных, 79.99 и 99.99 больше не проблема, но теперь более управляемая проблема с разными номерами …

 Original double: 39.99 Converted to NSDecimalNumber: 39.99000000000001024 

Во-первых, вы смешиваете некоторые термины. 79.98999999999999 – более высокая точность, чем 79.99 (имеет более длинное десятичное расширение), но более низкая точность (она отличается от истинного значения).

Во-вторых, NSNumber не хранит ни 79.99 ни 79.98999999999999 . Он сохраняет величину значения в соответствии со IEEE 754 . То, что вы видите, вероятно, является следствием логики печати, которая применяется для преобразования этой величины в читаемый человеком номер. В любом случае вы не должны полагаться на Float или Double для хранения значений с фиксированной точностью. По самой своей природе они жертвуют точностью, чтобы получить более широкий диапазон представимых значений.

Вам было бы намного лучше представлять цены как Int центов, или как NSDecimalNumber .

Пожалуйста, обратитесь к разделу Почему не использовать Double или Float для представления валюты?

Вот как удваивается работа везде. Если вам нужно всего 2 десятичных знака, подумайте об использовании integer / long вместо добавления точки после второй цифры, когда нужно отобразить значение.

  • Swift - Как создать пользовательский viewForHeaderInSection, используя XIB-файл?
  • Отключить и поп-просмотр контроллера
  • Назад к кнопке приложения, начинается через мое приложение
  • Ошибки обновления Parse Swift
  • iOS 10 Blur Effects Известные и регулярные неработающие
  • Как создать NSViewController в Swift?
  • AVPlayerItemDidPlayToEndTimeNotification не работает
  • Добавить UIPageViewController в текущем приложении
  • # прагма в Swift?
  • Добавление ошибки компоновщика Stripe
  • EXC_BAD_ACCESS «попытался сохранить освобожденный объект» в `deinit`
  • Interesting Posts

    Мое приложение вылетает, когда я пытаюсь зарегистрировать пользователя и активировать push-оповещения с помощью синтаксического анализа

    UINavigationBar: внешний вид работает, но не UINavigationBar: появлениеWhenContained in

    FacebookDisplayName на iOS с немецкими умляутами

    iOS mapView – перетащите штырь с одним касанием

    requestAnimationFrame undefined в iOS UIWebView?

    Лучшая практика iOS для обновления местоположения фона

    Выберите текст в текстовом поле UIAlertController

    Как получить значение цвета RGB от UISlider

    Модуль «Карты Google» не найден после добавления другой зависимости от Xcode

    как вернуть внешний вид UISegmentedControl?

    Изменение размера UITextView при открытии клавиатуры с автоматическим расположением

    Как удалить оригинальную WhatsApp UIActivity в UIActivityViewController?

    UITableView reloadData автоматически вызывает resignFirstResponder

    Потенциальная потеря доступа к цепочке ключей после приложения Перемещение учетной записи A на B в iOS

    Наблюдение за ключевыми значениями NSCache

    Давайте будем гением компьютера.