Format Stones and Pounds correctly?
delphi, delphi-xe, math, type-conversion
Solution
For pounds you get the fractional part with `Frac(weight)` and then multiply by 100. Then use `Round` to get it in integer form:
pounds := Round(100*Frac(weight));
And for stones it's just `Trunc`:
stones := Trunc(weight);
In the other direction you do:
weight := stones + pounds/100.0;
With these functions you can readily do the rest. The validity checks for values of pounds greater than 14 are easy to deal with. For example:
stones := Trunc(weight);
pounds := Round(100*Frac(weight));
stones := stones + pounds div 14;
pounds := pounds mod 14;
I'd be very surprised if you found this code anywhere in a general purpose library. That's because it's a very poor way to store weight. If you are going to use a floating point format you should do it like this:
weight := stones + pounds/14.0;
In the other direction you would do it like this:
stones := Trunc(weight);
pounds := Round(14*Frac(weight));
stones := stones + pounds div 14;
pounds := pounds mod 14;
Unfortunately you still need to do the div/mod shuffle. Imagine what happens when `weight=9.99`, for example.
Doing it this way makes arithmetic on the floating point values more sensible. For example, suppose you have measured weights of 10 people and want to know the total. It makes sense to do that with true floating point representation, but not with your representation.
To see that, suppose these 10 people, and they all weigh zero stones, 10 pounds. Very small people I know. But you would call that 0.1. Add up 10 lots of that and you have a weight of 1.0. But it's clear that the actual value is 100 pounds, or 7 stone two pounds.
But if you take 10 pounds and feed it into:
weight := stones + pounds/14.0;
then you find a weight value of 10/14. Add 10 lots of that to get 100/14, and well, I'm sure you get my drift!
The other obvious way to store such data is as pounds. Either integers or floating point could make sense.
Problem
I have a chart used to display weight in Stones and Pounds (lbs). The chart is populated by data from a record, for weight the data type is Double. The record data is edited at runtime and I need to know a way of formatting the entered data correctly. To better understand, first look at these sample values, they are represented as Stones and lbs: - 8.09 (8 stones and 9 lbs) - 12.03 (12 stones and 3 lbs) - 14.16 (14 stones and 16 lbs) - 11.13 (11 stones and 13 lbs) - 17.14 (17 stones and 14 lbs) There are only 14 pounds in a stone, so any value entered that is over .13 should increase the stones value by 1 and lower the pounds value starting back from .00 - so with that in mind, from the above sample two of those values are incorrect: - 14.16 - 17.14 they should be: - 15.02 - 18.00 Is there a built-in math function that can correctly format/round stones and pounds correctly? If not I would be really interested to see an answer that shows the logic or method of approach to solving this. I thought of checking the pounds part and if the value > 0.13 then I increment the stones, but then I am not sure how best to do this especially, if the value could be something like 13.76 then I wouldn't know what to change the stones and pounds into (this is where I start to confuse myself). Thanks in advance.