2012-03-02 1 views
3

3 캔을 포함하는 표준 상자가있는 시나리오가 있습니다. 디스플레이 및 쿼리 목적으로 표준 구성의 십진수로보고해야합니다. 그것은 등 3 캔 1 개 상자에 2 캔 1 상자를 ... 말을 할 수 없습니다
상자의 분수를 계산할 때 소수 정확도 손실

예를 들어, 처음에 나는 다음 결과 1 캔을 제거
3 캔 1 상자를해야합니다 3 캔
0.66 되풀이 상자에 내가 더 후 (1) 3 캔
0.33 되풀이 상자에 결과 수 그때 0.0000000000000000000000000001 상자 3 캔

0의 결과로 최종 캔을 삭제

마지막 깡통을 제거하면 값이 0 캔 3 캔 0 상자 0 개가 모두 원래 상자에서 제거 될 수 있기를 바랍니다. 유한 비트 수를 처리 할 때 0.33 반복을 나타낼 수 없다는 사실로 인해 정밀도가 손실된다는 점에 감사드립니다.

질문 : 반올림 (금융 어쩌면)을 사용해야하는 시스템에 더 많은 경험이있는 사람들을 위해이 문제를 해결할 수있는 옵션은 무엇입니까? 마지막 상자를 제거하게되면 상자가 더 이상 존재하지 않을 수 있습니다.

편집 :
결국. Loren Pechtel 제안을 사용하여 캔 수를 저장하면 총 상자 수를 표준 상자에있는 캔 수로 나눠 얼마나 많은 표준 상자를 표시해야 하는지를 재귀 적 결과를 얻을 수 있지만보고 할 때는 괜찮습니다. 사물의 측면. 여기

내가 좀 더 문제를 요약에 도움이되기를 바랍니다 몇 가지 코드입니다 : -입니다 그것을하지 않는 등의 문제

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

무한 정밀도 산술 라이브러리를 사용할 수 있습니다. – SLaks

+0

소수 대신 double을 사용하십시오. – jacknad

+0

처음에 두 번 시도했는데 세 번째 캔을 제거한 결과는 1.11022302462516E-16 of 3 – lostinwpf

답변

7

내 방식.

특히 재정적 일 때 그렇습니다.

일반적으로 재정적으로 다루기가 쉽습니다. 돈이 아닌 동전으로 모든 일을하십시오.

내 첫 번째 문제는 깡통 상자 대신 캔을 보관하는 것입니다. 그냥 표시 0으로하려면

+0

특정 상황에서 상자에있는 캔의 수는 다양 할 수 있다는 사실을 감안해야합니다. 캔을 보관하는 것이 더 좋을 수도 있다고 생각하기 시작 했음에도 불구하고 캔 수를 저장하는 것이이 문제를 해결할 지 확신 할 수 없습니다. – lostinwpf

1

후, 2 소수점 말은 합리적인 뭔가에 표시되는 정밀도를 설정합니다 비교

public override string ToString() 
{ 
    return _quantity.ToString("D2") + " of " + _box.Quantity.ToString(); 
} 

당신이 원하는 경우 0 값 (

public bool AreEqual(double value1, double value2) 
{ 
    double EPSILON = 0.000001; 
    return Math.Abs(value1 - value2) < EPSILON; 
} 

bool IsZero = AreEqual(_quantity,0); 
2

왜 당신의 수량에 대한 int를 사용하거나 다른 값), 일부 작은 값에 대한 차이를 비교? 어쨌든 1.078261563 (예를 들어) 캔 제거를 허용하려는 것 같지 않습니까?

조금 더 읽고 나면 여기서 딜레마를 볼 수 있다고 생각합니다. 크기 (상자의 최대 용량), 수량 (현재 상자에 포함 된 것)을 퍼센트 만 (크기 대 크기의 비율)로 결합하는 것 같습니다. 당신은 크기와 수량 및 퍼센트 전체 계산 추적, 약간 재 설계하는 경우, 나는 물건을 정리 것 같아요 :

class Box { 
    public decimal Size { get; private set; } 
    public decimal Quantity { get; private set; } 
    public decimal PercentFull { get { return this.Quantity/this.Size; } } 
    public Box(decimal size) { 
     this.Size = size; 
    } 
    public void Remove(decimal quantity) 
    { 
     this.Quantity -= quantity; 
    } 
    public void Add(decimal quantity) 
    { 
     this.Quantity += quantity; 
    } 
    public override string ToString() { 
     return this.PercentFull.ToString() + "% of " + this.Size.ToString(); 
      // Or, to be exact 
      // return this.Quantity.ToString() + " of " + this.Size.ToString(); 
    } 
} 

그것은 여전히 ​​(아마도 소독) 예에 따라, 보인다, 그 SizeQuantity는 것 int에 더 적합 할 수 있지만 수학은 같은 방식으로 작동합니다.

+0

간단한 예제로 저는 캔을 선택했습니다. 리터와 BOX 대신에 TUB 대신에 캔을 대신 쓰면 TUB에서 0.75 리터를 취해서 10 진수가 나에게 더 이해하기를 원할 것입니다. – lostinwpf