1

I am working on a calculation project which uses a lot of formulas. These formulas were defined for metrics Unit of measure(UOM) contains lot of constants. So if you give any data in Metric UOM (like kg,mm,km/h), it will give result. But as an enhancement, we need to introduce a feature which can accept data in English UOM (like lb,in,mph).

Now we tried to use the same formula, but it has lot of constants which were defined based on Metric UOM. So the calculated values are not matching and there is no way to change or redefine the rule engine based on English UOM. It may take long time and requires lot of approvals etc.We cannot change any thing on the formulas. So we convert the input English UOM values to Metric Units and performs calculation. But there is some deviation from the expected results.

I think the issue may be due to the converstion factor. For eg: if I convert 1kg (Metric UOM) to English UOM (pound). It will give around 2.20462. But when I convert this to Metric again, I am getting 0.9999988107 . So the final calculated result will have variations while performing calculation using same data. Is there any good approach to handle this one.
Thanks in advance for any ideas.

C# Code

public const double KG_LBS          =       2.205;
public const double LBS_KG          =       (1/KG_LBS);

static double ConvertKgsToLbs(string strInputValue, bool boolRoundWholeNum = false)
            {
                double dblInputValue = Convert.ToDouble(strInputValue);
                double dblResult = dblInputValue * KG_LBS;
                if (boolRoundWholeNum == true) dblResult = dblResult.WholeNumberRoundOff();
                return dblResult;
            }

static double ConvertLbsToKgs(string strInputValue, bool boolRoundWholeNum = false)
            {
                double dblInputValue = Convert.ToDouble(strInputValue);
                double dblResult = dblInputValue * LBS_KG;
                if (boolRoundWholeNum == true) dblResult = dblResult.WholeNumberRoundOff();
                return dblResult;
            }

Calculation error is happening like this.

1 kg = 2.20462 lb --1

2.20462 lb = 0.9999988107 kg --2

0.9999988107 kg = 2.20461999989109 lb --3

Step 1 , i did the first conversion from kg to lb. In Step 2 I did re conversion from lb to kg. The value is different. It's not 1, but its 0.9999988107. If I do a round I will get 1 If I am proceeding with the value in a formula. res=(weight*10)+200g

res= (1kg*10)+200g= 10.2kg -- when Kg=1 res= (0.9999988107kg*10)+200g= 10.199kg -- these change will effect on further calculation.

If you have any ideas to reduce this ,kindly share.

kbvishnu
  • 14,760
  • 19
  • 71
  • 101
  • Is there some c# code? – bokibeg Oct 15 '15 at 10:58
  • Without any information or code, it's hard to guess. Calculation errors though are usually caused by scaling errors when the `float` or `double` types are used. – Panagiotis Kanavos Oct 15 '15 at 11:02
  • And it's a double! You'll find that if you replace it with `decimal` the scaling errors will be reduced significantly, if not disappear – Panagiotis Kanavos Oct 15 '15 at 11:02
  • @DavidG there was no code until 40 seconds ago – Panagiotis Kanavos Oct 15 '15 at 11:03
  • @PanagiotisKanavos D'oh! – DavidG Oct 15 '15 at 11:04
  • Yes, use a Decimal but also try be more precise on the constants values – John-Philip Oct 15 '15 at 11:05
  • 1
    1kg is actually 2.20462262185 lbs if you want to be more accurate. – DavidG Oct 15 '15 at 11:08
  • Comments and the answer below are all correct but I tried your code and got whole numbers (though I don't know why do you use `string` parameters). Floating point issues usually happen when there are many steps in calculation, your formula is simple. Also, you can't get `2.20462` with above code due to constant being only `2.205`. – bokibeg Oct 15 '15 at 11:16
  • Thanks for all your comments. Initially there was no code. I added code later. Usage of string as parameter because, the values are entered in text box. Let me try to modify based on the below answers and suggestion. Also I some of issues I have please revisit the question once again – kbvishnu Oct 15 '15 at 12:41

1 Answers1

3

You've encountered floating point rounding issues. This happens because certain real numbers with a decimal representation can't be exactly represented in binary. For example, the exact value of KG_LBS isn't 2.205. It's 2.2050000000000000710542735760100185871124267578125. So once you start calculating with it, you'll get little discrepancies.

See: Is floating point math broken?

You might be able to solve your problem by using decimal instead of double.

Community
  • 1
  • 1
Rik
  • 28,507
  • 14
  • 48
  • 67