尝试计算一盒分数小数时precision亏损 [英] Decimal precision loss when trying to calculate fractions of a box

查看:92
本文介绍了尝试计算一盒分数小数时precision亏损的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一种情况,我有一个包含3罐标准箱。为了显示和查询的目的,我有在其标准配置的十进制量方面的报告。这是不可能说1盒3罐,1盒2罐...等

例如,一开始我将 1盒3罐
然后,我取出1罐造成3罐 0.66复发盒
然后我删除1更能造成3罐 0.33复发盒
然后我删除导致最终能 0.0000000000000000000000000001 中的3罐

当我删除了最后我能想的值为 0箱3罐作为每罐现在已经从原来的盒中取出。我AP preciate有一个为precision损失由于这样的事实,这是无法重新present 0.33时正在处理的比特的有限数量的重复。

问:谁的人有需要使用四舍五入(金融也许)我有哪些选择来处理这个问题的系统更多的经验?你怎么会去制作除去最后可能意味着中不再存在?

编辑:
最后。我用洛伦Pechtel建议和存储罐的数量,然后,当我需要证明我有多少标准箱分罐的总人数由罐在标准中仍然给出了一个递归结果的数目,但是,这是罚款的报告方面的事情。

下面是一些code,我希望将在概述帮助的问题更多一些: -

 静态无效的主要(字串[] args)
     {
        VAR箱=新StandardBox(3);
        VAR boxDetail =新BoxDetail(1.0M,盒);

        VAR allBoxes =新AllBoxes();
        allBoxes.AddBox(boxDetail);
        allBoxes.RemoveItemFromBox(boxDetail米,1.0米);
        Console.WriteLine(allBoxes);
        allBoxes.RemoveItemFromBox(boxDetail米,1.0米);
        Console.WriteLine(allBoxes);
        allBoxes.RemoveItemFromBox(boxDetail米,1.0米);
        Console.WriteLine(allBoxes);
        到Console.ReadLine();
    }
}

公共类StandardBox
{
    私人十进制_quantity;
    公共StandardBox(十进制量){_数量=数量;}
    公共小数数量{{返回_quantity; }}
}

公共类BoxDetail
{
    私人十进制_quantity;
    私人StandardBox _box;

    公共BoxDetail(十进制量,StandardBox盒)
    {
        _quantity =数量;
        _box =盒;
    }

    公共无效RemoveItem(十进制数量)
    {
        VAR newQuantity =数量/ _box.Quantity;
        _quantity = _quantity  -  newQuantity;
    }

    公共重写字符串的ToString()
    {
        返回_quantity.ToString()+的+ _box.Quantity.ToString();
    }
}

公共类AllBoxes
{
    私人列表< BoxDetail> allBoxes =新的名单,其中,BoxDetail>();

    公共AllBoxes(){}

    公共无效AddBox(BoxDetail盒){allBoxes.Add(盒);}

    公共无效RemoveItemFromBox(BoxDetail中,小数数量)
    {
        VAR boxDetailLineToModify = allBoxes.Find(B => b.Equals(盒));
        boxDetailLineToModify.RemoveItem(数量);
    }

    公共重写字符串的ToString()
    {
        VAR的结果=的String.Empty;
        的foreach(在allBoxes VAR盒)
        {
            结果+ = box.ToString()+\ N的;
        }
        返回结果;
    }
}
 

解决方案

我的做法,以这样的问题是不这样做。

这尤其是当它的财务的东西。

金融东西一般比较容易处理 - 你一切的工作便士,而不是美元

我的第一个反应,你的问题是将存储易拉罐罐身,而不是框。

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;
    } 
}

解决方案

My approach to such problems is don't do it.

That's especially true when it's financial stuff.

The financial stuff is generally quite easy to deal with--do all your work in pennies, not dollars.

My first reaction to your problem would be to store cans rather than boxes of cans.

这篇关于尝试计算一盒分数小数时precision亏损的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆