Richard Harnden <richard.harnden@googlemail.comwrites:
Quote:
I've got a list of longs which I need to fix.
>
Basically the numbers come from an unsigned long, which will wrap back
to zero.
I need them unwrapped.
>
Also, my data will come from a database which doesn't have an unsigned
long datatype ... they appear as long.
>
Does the following actually do what I hope it does?
|
Not quite (I think). It was only by reading the code I could decode
what you intended and if the code was further off the mark I would
have had to guess even more. I may still have guessed wrong!
Here is what I think you are doing: you have some process that
produces a sequence of numbers that you know to be strictly
increasing. However, due to some code you can't change, all you see
is the result after the sequence has been converted to a fixed-size
signed integer (long in this case) and from these numbers you need to
re-create the original sequence.
You can't do this from the data you have unless you add in the
assumption that the increments are never more than the maximum value
of an unsigned long. Give that assumption, your code is almost
correct but:
Quote:
#include <stdio.h>
#include <math.h>
#include <limits.h>
>
int main(void)
{
long testme[] = {
1649354396,
-1512698780,
-365331864,
856092536,
2076605992,
-1006418300,
191408540,
1462864659,
-1502144861,
-269042670,
910116600,
2098697218,
-971310087,
325728931,
1622242763,
-1378801075
};
size_t n = sizeof(testme) / sizeof(testme[0]);
size_t i;
unsigned long max = ULONG_MAX;
int wrapped = 0;
double value;
double prior_value = 0.0;
>
for (i=0; i<n; i++)
{
value = testme[i] + (wrapped * (double) max);
|
The value to multiply by should be max + 1. Clearly you need to write
that as + (wrapped * ((double)max + 1)) or some such.
Quote:
if ( value < prior_value )
{
wrapped++;
value += (double) max;
|
and again you need (double)max + 1 here. I'd define a double holding
(double)ULONG_MAX + 1 and use that instead of max.
Quote:
}
>
printf("%ld -%g\n", testme[i], value);
>
prior_value = value;
}
>
return 0;
}
|
There may also be problems using floating point arithmetic, especially
if the sequence is a long one. Can you use unsigned long long instead?
--
Ben.