Прежде чем даже думать об арифметике, вы должны знать, что double
это , а не подходящий тип данных для использования с валютой, потому что это неточно .Поэтому прекратите использовать тип с плавающей запятой (например, double
) в качестве типа данных для количества долларов и начните использовать точный тип (например, long
) в качестве типа данных для количества центов .
Шаги, необходимые для вычисления, должны состоять в немедленном преобразовании всего с округлением в центы:
double amountOwed = ...;
int noOfMembers = ...;
long centsOwed = Math.round(amountOwed * 100);
long portionCents = Math.round(amountOwed * 100 / noOfMembers);
long errorCents = portionCents * noOfMembers - centsOwed;
Вот один из способов справиться с ошибкой:
long lastPortionCents = portionCents - errorCents;
Но возможно, что ошибка превышает 1 цент, поэтому лучшим решением будет равномерное распределение ошибки путем вычитания (или добавления, если ошибка отрицательная) 1 цента от первого(или последний, или случайным образом выбранный) errorCents
закусочных.
Остальная часть решения состоит в том, чтобы разорвать вышеупомянутое, которое я оставляю читателю.
В качестве примечания, используяценты - это то, как банки передают суммы (по крайней мере, для EFTPOS).
Что касается базового дизайна программного обеспечения, я бы создал отдельный метод, который принимает целочисленные центы и количество людей в качестве параметров и возвращает массивиз «разделенных» сумм.Это не только облегчит чтение вашего кода, но и разделит арифметическую операцию и, таким образом, позволит с лёгкостью писать множество простых тестов, чтобы вы знали, что у вас есть все крайние случаи, о которых вы можете подумать.