Действительно ли NSDecimalNumber необходим для выполнения довольно простых задач? - PullRequest
1 голос
/ 02 августа 2010

Началось вполне нормально.Я пишу сложное приложение для расчета для iPhone.Я решил использовать float примитив для представления чисел.Итак, пришло время начинать округление и форматирование вывода, но прежде всего округление.Я хочу округлить числа в разное количество знаков после запятой.НАЙТИ нет полезной функции C.ОК, так что я могу написать свой собственный.Но тогда у меня есть номера из настроек приложения, чтобы сохранить.Я обнаружил, что только объекты могут быть сохранены.Поэтому я начал копаться в NSNumber и NSDecimalNumber.Особенно последний дает мне дрожь только тогда, когда на нее смотрят.Делегат должен был реализовывать округления, а не арифметические операторы smiple, вместо этого специальные методы .... :( Что же тогда остается от простоты простого C?

Есть ли другой способ упростить это?

Ответы [ 2 ]

3 голосов
/ 02 августа 2010

Возможно, вы можете использовать theValue - fmod(theValue, 0.01) для округления, например, до ближайшего 0,01.) Но будьте осторожны!

Компьютеры на самом деле не работают с десятичными числами - т.е. числа в базе десять, как мы их используем в обычной жизни. Они работают с двоичными числами, и это включает числа с плавающей точкой. Они также представлены в двоичном формате, и это означает, что «число десятичных разрядов» не всегда является значимым свойством числа с плавающей запятой.

Например, число с плавающей запятой не может точно представлять 0,1, и вы получите что-то вроде 0,1000000001, если попытаетесь использовать его в своем коде. Точное значение, которое вы получаете, зависит от реализации и не может быть исправлено путем вычитания разницы, так как компьютер не может сказать, что есть разница - это настолько близко, насколько это возможно, к 0,1.

Вот почему существуют такие классы, как NSDecimalNumber. Они моделируют десятичную математику, чтобы дать значения, которые кажутся нам более разумными. Они подвержены многим из тех же проблем, что и с плавающей запятой, но с разными значениями (например, 1.0 / 3.0 не совсем точно представляется в десятичном виде, но это все же дискретное значение.)

Так что да, если ваши числа должны быть округлены до определенного количества десятичных знаков, вам нужно использовать NSDecimalNumber для большинства десятичных операций. Если это только для отображения, вы можете использовать что-то вроде NSNumberFormatter вместо того, чтобы получить отображаемое значение без изменения самого числа в памяти.

Вторая часть вашего вопроса - сохранение числовых значений в пользовательских значениях по умолчанию - легко решается. NSNumber «оборачивает» примитивный числовой тип, но его можно развернуть:

NSNumber *n = [NSNumber numberWithDouble: 1.234567890];
double aDouble = [n doubleValue];
2 голосов
/ 02 августа 2010

Используйте NSDecimal и NSDecimalNumber всякий раз, когда вам нужна точная точность, особенно для любых бухгалтерских / финансовых операций. Для всего, что требует точности, но для которой вам не нужна точность точная , используйте double, а не float. NSNumber - это просто объектная оболочка Obj-C для числовых примитивов.

Для форматирования и округления посмотрите на NSNumberFormatter. Любой примитивный номер C может быть заключен в NSNumber, тогда вы можете использовать NSNumberFormatter для преобразования его в NSString. Поначалу это может показаться несколько неуклюжим, но в реальных условиях это работает довольно хорошо, поскольку вы получаете очень высокий уровень контроля форматирования.

...