2012-04-06 5 views
6

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

Например,

Когда вошли: "32 + 32,1" Результат: "+64,0999999999999"

Кроме того, я должен отметить, что это происходит довольно часто при использовании научной нотации. "(2,3 * 10^23) * (1,452 * 10^23)" Возвращает: "3.339599999999999999e + 46"

И, наконец, иногда число, которое возвращает: отл. 123.0000000000001

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

EDIT

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

answer.text = [NSString [email protected]" %g ", doubleAnswer]; 

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

ответ

8

Номера с плавающей запятой не очень хорошо обозначают конкретные цифры. Использование double's сделает это случаться реже, но у вас все еще будет проблема. Для технического описания того, как хранятся числа с плавающей запятой (и почему у нас есть эта проблема в первую очередь), см. Эту статью в википедии: 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 
+1

ahh true true, но что, если бы я хотел отображать его как 62.1, но все же оставляю возможность отображать 64.1065 например (это то, что я ищу, кстати, спасибо.) –

+1

Тогда вам либо нужно отслеживать десятичные знаки, которые вы хотите отобразить (беспорядочно) или не использовать float, и переходить к переменной типа пыльника (возможно, 'NSDecimalNumber'). – lnafziger

+1

Я попробую. –

2

Вы не можете «исправить» число с плавающей запятой, потому что числа с плавающей запятой просто не могут представлять нужный номер.

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

Вместо этого используйте double. Они могут представлять гораздо больший диапазон значений и, как результат, могут представлять собой гораздо больше значений совершенно точно. Если это не достаточно, вам нужно перейти к чему-то с большей точностью. Возможно NSDecimalNumber.

Смежные вопросы