У меня есть сценарий, в котором у меня есть стандартный ящик, содержащий 3 банки. Для отображения и запросов я должен сообщать о десятичной сумме стандартной конфигурации. Это невозможно сказать, 1 коробок 3 банок, 1 коробок 2 банок ... и т.д.
Десятичная точность потери при попытке вычисления долей поля
Например, сначала у меня будет 1 коробка 3 банок
Я тогда удалить 1 может в результате в 0,66 повторяющейся коробки 3 банок
я затем удалить 1 больше, в результате чего может 0.33 повторяющейся коробка 3 банок
потом удалить окончательную банку в результате 0,0000000000000000000000000001 коробки из 3 банок
Когда я удаляю окончательный вариант, я хотел бы, чтобы значение было 0 ящиков из 3 банок, поскольку каждый из них теперь удален из оригинальной коробки. Я ценю, что есть потеря точности из-за того, что невозможно представить 0.33, повторяющийся, когда вы имеете дело с конечным числом бит.
Вопрос: Для людей, которые имеют больше опыта в системах, которые должны использовать округление (возможно, финансовые), каковы мои варианты решения этой проблемы? Как вы могли бы сделать удаление последнего, может означать, что ящик больше не существует?
Редактировать:
В конце концов. Я использовал предложение Лорена Пехтеля и записал количество банок, а затем, когда мне нужно показать, сколько стандартных ящиков я делю общее количество банок на количество банок в стандартном ящике, которое все еще дает рекурсивный результат, но это отлично подходит для отчетов стороны вещей.
Вот код, который я надеюсь, поможет с изложением проблемы еще немного: -
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;
}
}
Вы можете использовать арифметическую библиотеку с бесконечной точностью. – SLaks
Используйте double вместо десятичного. – jacknad
Сначала я попытался удвоить, и результат удаления 3-го банка - это 1.11022302462516E-16 из 3 – lostinwpf