I have a scenario where I have a standard box that contains 3 cans. For display and query purposes I have to report in terms of a decimal amount of its standard configuration.It is not possible to say 1 box of 3 cans, 1 box of 2 cans...etc
For example, initially I will have 1 box of 3 cans
I then remove 1 can resulting in 0.66 recurring box of 3 cans
I then remove 1 more can resulting in 0.33 recurring box of 3 cans
I then remove the final can resulting in 0.0000000000000000000000000001 box of 3 cans
When I remove the final can I would like the value to be 0 boxes of 3 cans as every can has now been removed from the original box. I appreciate that there is a loss of precision due to the fact that it is not possible to represent 0.33 recurring when you are dealing with a finite number of bits.
Question: For people who have more experience in systems that need to use rounding (financial maybe) what are my options to deal with this problem? How would you go about making the removal of the last can mean that the box no longer exists?
Edit:
In the end. I used Loren Pechtel suggestion and stored the number of cans then when I need to show how many standard boxes I divide the total number of cans by the number of cans in a standard box which still gives a recursive result but this is fine for the reporting side of things.
Here is some code which I hope will help in outlining the problem some more:-
static void Main(string[] args)
{
var box = new StandardBox(3);
var boxDetail = new BoxDetail(1.0m, box);
var allBoxes = new AllBoxes();
allBoxes.AddBox(boxDetail);
allBoxes.RemoveItemFromBox(boxDetail, 1.0m);
Console.WriteLine(allBoxes);
allBoxes.RemoveItemFromBox(boxDetail, 1.0m);
Console.WriteLine(allBoxes);
allBoxes.RemoveItemFromBox(boxDetail, 1.0m);
Console.WriteLine(allBoxes);
Console.ReadLine();
}
}
public class StandardBox
{
private decimal _quantity;
public StandardBox(decimal quantity){_quantity = quantity;}
public decimal Quantity {get { return _quantity; }}
}
public class BoxDetail
{
private decimal _quantity;
private StandardBox _box;
public BoxDetail(decimal quantity, StandardBox box)
{
_quantity = quantity;
_box = box;
}
public void RemoveItem(decimal quantity)
{
var newQuantity = quantity / _box.Quantity;
_quantity = _quantity - newQuantity;
}
public override string ToString()
{
return _quantity.ToString() + " of " + _box.Quantity.ToString();
}
}
public class AllBoxes
{
private List<BoxDetail> allBoxes = new List<BoxDetail>();
public AllBoxes(){}
public void AddBox(BoxDetail box){allBoxes.Add(box);}
public void RemoveItemFromBox(BoxDetail box, decimal quantity)
{
var boxDetailLineToModify = allBoxes.Find(b => b.Equals(box));
boxDetailLineToModify.RemoveItem(quantity);
}
public override string ToString()
{
var results = string.Empty;
foreach (var box in allBoxes)
{
results += box.ToString() + "\n";
}
return results;
}
}