-2
#region Weights
private double StoneToKg(double Stone, double pounds)
{
    return (Stone * 14 + pounds) * 0.4535970244035199;
}
private double[] KgToStone(double p)
{
    double T = (p * 0.1574714285714286);
    double Stn = Math.Floor(T);
    double Pounds = (T - Stn) * 14;
    return new double[2] { Stn, Pounds };
}
#endregion
#region Heights
private double CmToM(double Cm)
{
    return Cm * 0.01;
}
private double MToCm(double M)
{
    return M * 100;
}

private double FeetToMeters(double Feet, double inch)
{
    Feet *= 12;
    return (Feet + inch) * 0.025399999961392;
}
private double[] MetersToFeet(double Meters)
{
    double feet = Math.Floor(Meters * 3.2808399);
    double inch = (Meters * 3.2808399) - Math.Floor(Meters * 3.2808399);
    inch *= 12;
    return new double[2] { feet, inch };
}
private double feetInchToCentimeters(double feet, double inch)
{
    return MToCm(FeetToMeters(feet, inch));
}
private double[] CentimetersToFeetInch(double Cm)
{
    return MetersToFeet(CmToM(Cm));
}
#endregion

This is the conversion code I'm using, currently having issues converting from stone to kg and back (100 stn 0 pounds to kg and back gives 107 stn and 2.00000000000014 pounds) but converting 100 kg to stone and back works, I think it's rounding the answer but I am unsure where or how to fix, looking for a way to make an accurate conversion which can handle conversions to and from.

Any other code tying and suggestions are welcome however.

(I included the height conversions in-case there is a problem with that too).

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Rhys
  • 1
  • 1
  • 8
  • Don't you need to know the substance being measured, its location, and the date to determine the conversion factor? See [here](http://www.britannica.com/EBchecked/topic/567177/stone) and [here](http://en.wikipedia.org/wiki/Stone_(unit)). – HABO Feb 24 '13 at 16:00

4 Answers4

2

When I try the code, I don't get the result that you say:

double kg = StoneToKg(100, 0);

Console.WriteLine(kg);

double[] st = KgToStone(kg);

Console.WriteLine(st[0]);
Console.WriteLine(st[1]);

Output:

635,035834164928
100
1,98951966012828E-13

That's not 107 stones and 2 pounds, that's 100 stones and 0.0000000000002 pounds.

That is well within the precison that you could expect using double precision math.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
1

If I might weigh in here (sorry for the pun)...

This is really two problems. The code seems to be a trivial problem compared with the real problem, which many students tend to struggle with. That problem is unit conversion and significant figures.

According to Wikipedia, a Stone is equal to approximately 6.35 kg and is used to measure body weight. So, if you are trying to convert stone to kg, you need to return 6.35029 * (#ofStones), rounded to the nearest hundredth (or thousandth) depending on the precision of your inputs.

Now on to the second problem, the precision of your inputs. It seems like you would want to use integer inputs for the stones and pounds, otherwise it makes no sense to separate them out like that. To get the decimal number of stones, you need to multiply the integer number by 14, then add the pounds, then divide the whole thing by 14 and multiply by 6.35029:

[(intStones * 14) + pounds]/14 * 6.35029 --> round to the nearest hundredth

Does this make sense? Then for your convert back, I recommend using integers as follows (note that integer division and multiplication rules automatically truncate decimals):

public void KgToStoneAndPounds(double kg, out int stones, out int pounds)
{
    //Convert kg to lbs (keep sig fig rules, I always go one extra place in intermediate calculations)
    double totalPounds = Math.Round(kg * 2.20462, 3);

    stones = totalPounds / 14;
    pounds = Math.Round(totalPounds - (stones * 14), 0);
}

This will give you good enough numbers from a scientific perspective.

theMayer
  • 15,456
  • 7
  • 58
  • 90
  • ok i made some eddits, there was a gui error resulting in the 107, and i fixed the formula so it used the inverse of the other conversion, so *comv to go one way and /comv comv= 0.4535970244035199 'private static double StoneToKg(double Stone, double pounds) { return (Stone * 14 + pounds) * comv; } private static double[] KgToStone(double p) { double T = (p / comv ); int Stn =(int)Math.Floor(T/14); double Pounds = T % 14; return new double[2] { Stn, Pounds }; }' – Rhys Feb 24 '13 at 18:00
  • Why are you returning a double[2]? At the very least, I would expect integer[2], but to be more clear, it's better to use output parameters. – theMayer Feb 24 '13 at 23:15
0

For any business calculations, the best practice is to use BigDecimal with precision and rounding, instead of float or double.

For detailed reasons why float and double are suited to purely mathematical and geometric calculations, please see: Best Practice for financial calculations using JSTL/Tomcat

Community
  • 1
  • 1
Akber Choudhry
  • 1,755
  • 16
  • 24
  • -1 The reasons are well within the scope of this question. If you're going to tell someone not to use floating point types, you should explain why or at least point to another question or other resource that does. – Caleb Feb 24 '13 at 16:09
  • Yes, I should have done that. Done. – Akber Choudhry Feb 24 '13 at 16:13
  • whats a big decimal? sorry i haven't been coding long bout a year i think – Rhys Feb 24 '13 at 16:19
  • Sorry, my mistake - it is C# and not java. Please see this: http://stackoverflow.com/questions/2863388/what-is-the-equivalent-of-the-java-bigdecimal-class-in-c – Akber Choudhry Feb 24 '13 at 16:24
  • I'm not sure this is necessary. You merely have the illusion of additional precision, when in fact the original inputs are not that precise to begin with. Got to remember significant figure rules. – theMayer Feb 24 '13 at 16:37
0

One stone is 6.35029 kg, and there are 14 lbs per stone. So ...

const double KgPerStone = 6.35029;
const double PoundsPerStone = 14;

public double StonesToKg(double stones, double pounds)
{
    double totalStone = stones + (pounds / PoundsPerStone);
    return totalStone * KgPerStone;
}

public double KgToStones(double kg, out pounds)
{
    double totalStone = kg / KgPerStone;
    double stone = Math.Truncate(totalStone)
    double frac = totalStone - Math.Truncate(stone);
    pounds = frac * PoundsPerStone;
    return stone;
}
Jim Mischel
  • 131,090
  • 20
  • 188
  • 351