2013-06-18 2 views
2

Вот код:Objective-C: floorf() возвращает неверное значение

float passedPrice = 2.953; 
    float placed = 1000.0; //3 decimals 
    NSLog("%f", placed); // Gives 2953; 
    float withNoFractions = floorf(passedPrice * placed); 

Значение, сохраненное в withNoFractions является 2952! Это будет 2953. Что действительно странно, так это то, что он работает некоторое время.

+0

[Что каждый программист должен знать о плавающей точкой] (https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&ved=0CDQQFjAB&url=http%3A% 2F% 2Ffloating-point-gui.de% 2F & ei = tqq_UcPJKsav0AHymoDgCg & usg = AFQjCNEZ7cdKN5bOhpWTIQQCev6G53AQYg & sig2 = Ou9Gjbv655Pv6sQErqscMw & bvm = bv.47883778, d.dmQ) – Barmar

+0

Я взглянул на статью. Тем не менее, это не решает проблему. прошлоЦена * помещена = 2953 не 2952. Почему настил дает 2952? –

ответ

7

Многие десятичные числа с плавающей запятой не могут быть представлены как точные дроби в двоичном формате, поэтому их необходимо приблизить. 2.953 приближается как что-то вроде 2.95299999. Если умножить на 1000, результат 2952,99999, и когда вы получите пол этого, это 2952.

Чтобы решить эту проблему, вы можете использовать либо round() вместо ffloorf(), или вы можете добавить 0,5 до вызова ffloorf():

float withNoFractions = floorf(passedPrice * placed + 0.5); 
+0

Да, вы правы. Я использовал «po» в Xcode вместо NSLog(), который дает ваш ответ. Как это решить? –

+0

Спасибо, Бармар. Я столкнулся с проблемой, связанной с этим алгоритмом, и открыл еще один вопрос: http://stackoverflow.com/questions/17159611/objective-c-flooring-to-3-decimals-correctly –

+0

Это похоже на ту же проблему. Вы используете это решение, а затем разделите его на 1000. – Barmar

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