Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old September 4th, 2008, 12:05 PM
Richard Harnden
Guest
 
Posts: n/a
Default unsigned long to double

Hi,

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?

#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);

if ( value < prior_value )
{
wrapped++;
value += (double) max;
}

printf("%ld -%g\n", testme[i], value);

prior_value = value;
}

return 0;
}
  #2  
Old September 4th, 2008, 02:15 PM
Ben Bacarisse
Guest
 
Posts: n/a
Default Re: unsigned long to double

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.
  #3  
Old September 4th, 2008, 02:45 PM
viza
Guest
 
Posts: n/a
Default Re: unsigned long to double

On Thu, 04 Sep 2008 04:02:18 -0700, Richard Harnden wrote:
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?
Doing this in floating point is a very bad idea. On most systems double
cannot represent all the integers in the range of long, so if you have
large numbers they will get rounded to the nearest multiple of two or
four or eight etc, depending on their mangitude.

It is also much slower.

Converting an unsigned long int to a long int produces implementation
defined results if is outside the range of long int, so you need to test
what the output of the system that put the numbers into the database, but
in most cases, it is sufficient to do:

{
long testme= FOO;
unsigned long corrected;

corrected= testme;
}

HTH
viza
  #4  
Old September 4th, 2008, 04:35 PM
Boon
Guest
 
Posts: n/a
Default Re: unsigned long to double

viza wrote:
Quote:
Doing this in floating point is a very bad idea. On most systems
double cannot represent all the integers in the range of long,
Are you thinking of systems where longs are 64-bits wide?
  #5  
Old September 4th, 2008, 04:35 PM
jameskuyper@verizon.net
Guest
 
Posts: n/a
Default Re: unsigned long to double

viza wrote:
Quote:
... On most systems double
cannot represent all the integers in the range of long, so if you have
I agree that you should not write code which assumes that long
integers can be converted to double without loss of precision.
However, I'm think that you may be overstating your case by using the
word "most". I don't know exact numbers, but it seems to me that
implementations with 32-bit longs are still pretty common. The
standard permits "double" to have insufficient precision to represent
a 32-bit integer, but I doubt that implementations where this is the
case are common. Most implementations I'm familiar with use IEEE
format double precision, which has nearly twice that capacity.
  #6  
Old September 4th, 2008, 05:55 PM
viza
Guest
 
Posts: n/a
Default Re: unsigned long to double

On Thu, 04 Sep 2008 08:33:42 -0700, jameskuyper wrote:
Quote:
viza wrote:
Quote:
>On most systems double cannot represent all the integers in the
>range of long
>
I agree that you should not write code which assumes that long integers
can be converted to double without loss of precision. However, I'm think
that you may be overstating your case by using the word "most".
perhaps ..."most systems (that I'm sitting at)"...
:-)
 

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles