Вопрос по iphone, cocoa, ios, xcode – Исправление чисел с плавающей запятой

6

Мне интересно, можно ли легко и безопасно исправить числа с плавающей запятой.

Например

При вводе: «32 + 32,1» Результат: «64.0999999999999»

Также я должен отметить, что это происходит довольно часто при использовании научных обозначений. "(2.3 * 10 ^ 23) * (1.452 * 10 ^ 23)" Возвращает: "3.339599999999999999e + 46"

И, наконец, иногда возвращаемое число: напр. +123,0000000000001

Спасибо за помощь

РЕДАКТИРОВАТ

Ответ, который был одобрен, великолепен. Но то, что я нашел, сработало для меня, использовав% g с двойным в NSString stringWithFormat. % g, кажется, округляет все достаточно правильно. напр.

<code>    answer.text = [NSString [email protected]" %g ", doubleAnswer];
</code>

Использование удваивает ваши расчеты, а затем использование этого метода, похоже, работает для меня, и я надеюсь, что это поможет и другим. Если это не тот ответ, который вы ищете, проверьте утвержденный ответ!

Ваш Ответ

1   ответ
8

. Использование двойных сделает это случаться реже, но у вас все еще будет проблема. Техническое описание того, как хранятся числа с плавающей запятой (и почему мы имеем эту проблему в первую очередь), смотрите в этой статье в Википедии:IEEE 754-1985. (По сути, числа с плавающей запятой хранятся в виде двоичного представления значения и имеют только столько битов, которые можно использовать, поэтому они быстро заканчиваются и должны округляться до ближайшего значения, которое они способны представить.)

Как правило, вы не беспокоитесь о +/- .0000001 и просто форматируете их, когда хотите отобразить их пользователю с соответствующим количеством десятичных знаков, и оно будет округлено. Внутренне это не имеет значения, как оно хранится.

Например, если вы хотите отобразить «результат», вы можете сделать что-то вроде этого:

float myFloat = 32 + 32.1;
NSString *result = [NSString stringWithFormat:%@"%.2f", myFloat];
// result will contain 64.10

Если вам не нужно фиксированное количество десятичных знаков, вы также можете использовать возможность преобразования с плавающей точкой в строкуNSNumber:

float myFloat = 32 + 32.1;
NSNumber *myNumber = [NSNumber numberWithFloat:myFloat];
NSString *result = [myNumber stringValue];
// result will contain 64.1

NSDecimalNumber позаботится обо всем этом для вас, но это немного сложнее и требует больше накладных расходов, но вот пример для начала:

NSDecimalNumber *num1   = [NSDecimalNumber decimalNumberWithString:@"32"];
NSDecimalNumber *num2   = [NSDecimalNumber decimalNumberWithString:@"32.1"];
// Or since you use exponents:  
// NSDecimalNumber *num2   = [NSDecimalNumber decimalNumberWithMantissa:321 exponent:-1 isNegative:NO];

NSDecimalNumber *myNumber = [num1 decimalNumberByAdding:num2];
NSString *result = [myNumber stringValue];
// result will contain 64.1

Похожие вопросы