views:

115

answers:

5

I know there must be a generic method but I don't even know the term to search for and I don't want to re-invent the wheel, badly.

'Separate components values' and 'composite values' don't give good results.

another example: degrees+minutes+seconds from seconds of arc, or tons+pounds+ounces from ounces.

I'm working in C but it shouldn't be too hard to translate from some other language.

The inputs would be the basic value, say total inches= 9534567, and the unit divisions, like feet=12, yards=feet*3, miles=yards*1760. The output would be 150 miles, 849 yards, 0 feet and 3 inches.

Surely this can be generalized to use some other set of unit divisions. And a whole library seems like overkill, doesn't it?

+1  A: 

There's no generic way for every composite value. Each of the examples you gave are fairly radically different in the 'splits' for each one. The worst of course being dates due to the differences in length of months etc.

For the others, you probably could manage something along the lines of providing a list of the 'cutoffs' for each value and being returned a list of each one. Then you pretty much just have modulus and division operations to split the value down.

workmad3
+1 for "modulus", which I think is the desired answer
chrispy
A: 

Mathematically this is integer division with remainder.

In C (and Java, ...) you can use the / and % operators to compute quotient and remainder, respectively.

Edit:

1249559005844: "6. August 2009 11:43:25 UTC"
1249559005844 % 1000 = 844
1249559005844 / 1000 = 1249559005
1249559005 % 60 = 25
1249559005 / 60 = 20825983
20825983 % 60 = 43
20825983 / 60 = 347099
347099 % 24 = 11
347099 / 24 = 14462

Above days it gets messy, because months and years have different lengths.

starblue
Would you care to show an example for interested parties who have been programming for only a short time?
willc2
Even below days it's messy - due to daylight savings time, you can have a day of 23 or 25 hours, making "24 hours later" and "next day, same time" not always the same thing.
Michael Borgwardt
@Michael Borgwardt But that is a different mess. You can take time zones and such into account after splitting the raw time into components. Also, the world would be a better place without daylight savings time, less complexity and more time to sleep.
starblue
And then there are also leap seconds ...
starblue
I don't think trying to apply time zones as an afterthought would work - it's just a bad mistake to think that time calculations can be done that way. There are libraries for that kind of thing. Use them. Especially when they come with the language as in Java. But I do agree that daylight savings time is a thoroughly pointless addition to the mess that dates are. Leap seconds are thankfully rarely relevant.
Michael Borgwardt
A: 

Converting between units mathematically merely involves a simple one or two step process of division or multiplication depending on which way you are going between units. A simple example is the logarithmic scale of the metric system: To go from metres to centimeters you multiply by 100 because there is 100 centimetres in a metre.

I don't know any C but all you really need to know is the conversion factor and whether you are going up or down in unit magnitude. This should work for well designed systems like the metric system where things go in a logarithmic scale but where the conversion factors differ as in the imperial system you will run in to trouble if you are trying to convert with a single factor. You could just have your program go recursively up or down different units. So you could go:

Metres  (n*100)-> cm (cm*10) -> mm (mm*1000) -> µm

And then division would just go in revers, keeping the conversion factors the same.

Moral of the story: don't use the imperial system.

Jonno_FTW
It's a good thing we use the metric system for time then.
willc2
http://zapatopi.net/metrictime/But the 60 seconds / minute goes back to when the Babylonians thought there was 360 days in a year.
Jonno_FTW
+1  A: 

In most cases the computations are pretty straight-forward, though it can be tedious to code all of the conversion factors.

However the computations involving duration are conceptually difficult. How many days are there in a year? Is it 365 ... or 366? How many seconds in a year?

Stephen C
even the number of hours in a day is not fixed...
Michael Borgwardt
+1  A: 

As mentioned, this is more difficult when dealing with non-standard lengths of intermediate elements. However, given a standard set of breaks you could compute using the following:

void components (long value, long * parts, int parts_sz, long * result) {

    int i = 0;
    for (; i < parts_sz; ++i) {
        result[i] = value / parts[i];
        value %= parts[i];
    }
}

int main () {

    int i = 0;
    long parts[] = {10000, 1000,100,10,1}, result[] = {0,0,0,0,0};
    long value = 99853;

    components (value, parts, 5, result);

    for (; i < 5; ++i)
        printf ("There were %ld %lds\n", result[i], parts[i]);

    retrun 0;
}

Which yields:

There were 9 10000s
There were 9 1000s
There were 8 100s
There were 5 10s
There were 3 1s
ezpz
How about if the breaks were of fixed but differing lengths like miles + yards + feet + inches?
willc2
Right, but if the arguments were all represented by the same base it wouldnt matter. For instance yards/feet/inches would be components(36,12,1)
ezpz
And they said it couldn't be done.
willc2