Раньше я работал в основном с целыми числами, и в ситуациях, когда мне нужно усечь число с плавающей запятой или удвоить его до целого числа, я бы использовал следующее перед:
(int) someValue
пока я не узнал следующее:
NSLog(@"%i", (int) ((1.2 - 1) * 10)); // prints 1
NSLog(@"%i", (int) ((1.2f - 1) * 10)); // prints 2
(см. Странное поведение при приведении числа с плавающей запятой к типу int в C#для объяснения ).
Короткий вопрос: :как мы должныобрезатьчисло с плавающей запятой или двойное число правильно? (В данном случае требуется усечение, а не "округление" ). Или, можно сказать, что поскольку одно число равно 1,99999999999999, а другое — 2,000000000000001 (, грубо говоря ), усечение выполняется правильно. Итак, вопрос в том, как нам преобразовать float или double, чтобы результатом было «усеченное» число, имеющее общий смысл?
(намерение не состоит в том, чтобы использовать round
, потому что в этом случае для 1.8
нам нужен результат из 1
вместо2
)
Более длинный вопрос:
Я использовал
int truncateToInteger(double a) {
return (int) (a + 0.000000000001);
}
-(void) someTest {
NSLog(@"%i", truncateToInteger((1.2 - 1) * 10));
NSLog(@"%i", truncateToInteger((1.2f - 1) * 10));
}
и оба печатаются как 2
, но это кажется слишком большим хаком, и какое небольшое число мы должны использовать, чтобы «убрать неточность»? Есть ли более стандартный или проработанный способ, вместо такого произвольного взлома?
(Обратите внимание, что нам нужно усечение, а не округление в некоторых случаях, например, скажем, если количество секунд равно 90 или 118, когда мы показываем, сколько минут и сколько секунд прошло, минуты должны отображаться как 1
, но не следует округлять до2
)