Как мне умножить это в C?

Я писал программу, которая принимает входные данные в долларах от пользователя и преобразует их в целые, которые являются центами. Пользователь всегда будет вводить либо целое число, либо число с плавающей запятой с максимум двумя десятичными знаками. Я хочу преобразовать его в int, умножив на 100. Однако программа не работает для некоторых чисел.

int cents = (dollars*100);

dollars - это ввод с плавающей запятой, который дает пользователь. Например, если I dollars = 4,2, cents становится 419,999. Как я могу исправить эту проблему?


person Shaurya Gupta    schedule 25.01.2014    source источник
comment
используйте большой целочисленный тип, такой как long cents, чтобы сохранить всю сумму (например, 14000,99 долларов США - это 1400099 центов) и просто печатайте явно доллары и центы всякий раз, когда вы печатаете. Например. long cents = 1400099; printf("You've got $%ld.%02ld\n", cents/100, cents%100);   -  person Brandin    schedule 25.01.2014


Ответы (3)


Просто отрегулируйте значение следующим образом:

int cents = (int)(dollars*100 + 0.5);
person Paul Evans    schedule 25.01.2014
comment
Почему вы произвольно добавляете 0,5? Вы хотите, чтобы банк потерял деньги - person Brandin; 25.01.2014

Вы не можете это исправить. Числа с плавающей запятой не имеют «десятичных знаков». Они всегда приблизительны и нечетки. Никогда не используйте числа с плавающей запятой для денег — это одно из самых важных правил программного обеспечения, которое имеет дело с чем-либо финансовым. Прочитайте ввод в виде строки (%s) и соедините центы, найдя десятичную точку в строке, а затем используя atoi в частях до и после ..

person librik    schedule 25.01.2014
comment
+1 Согласен. Но на практике я никогда не видел, чтобы кто-то использовал для расчетов в страховом секторе что-либо иное, кроме удвоения. В моей компании это даже письменное требование. При всех проблемах, к которым это приводит... - person Axel; 25.01.2014
comment
@Axel, почему бы вам не использовать специализированный класс для работы с деньгами, а просто использовать это требование для работы с деньгами. Это называется разделение интересов - person Brandin; 25.01.2014
comment
Требование состоит в том, чтобы использовать машинный тип данных двойной точности. Реализация специализированного класса, который делает все точно так же, как и double, приведет к накладным расходам. - person Axel; 25.01.2014
comment
И люди спрашивают, почему COBOL все еще существует. Это именно то, с чем COBOL (который раньше использовался повсеместно в страховом секторе) просто фантастический. Интересно, кто бы ни написал требование вашей компании, не понял, от чего они отказались, когда перешли от спецификаторов PIC (т. Е. Фиксированного десятичного числа) к удвоениям, когда компания сменила язык. - person librik; 26.01.2014

1) Вероятно, вы можете настроить модель точности с плавающей запятой в свойствах вашего проекта
2) При преобразовании из числа с плавающей запятой в целое всегда удобно добавить немного, чтобы разрешить округление:

int cents = ((dollars*100.0)+0.5);
person noelicus    schedule 25.01.2014