Initializing a double to INT_MAX + 1
Hi,
I'd like to set a double's start value at the maximum possible value a int can hold, +1.
i.e., if the int is 32 bit long, I'd like to write:
Code:
double a = 0x100000000;
However, I get a compile error of "integer constant is too large for "long" type "
At best, I can write this:
Code:
double a = static_cast<double>(0xffffffff) + 1;
Also, since I'd like the code to be portable, using 0xffffffff doesn't really work, so I use this:
Code:
double b = static_cast<double>(static_cast<unsigned int>(-1)) + 1;
This not only doesn't look very clean, I'm pretty sure it's not even accurate if my long is 8 bytes. Also, I'd like my double to be evaluated at compile time, not run time.
Can anybody help?
I thought at worst, I can do something like:
Code:
double c = pow(2,8*sizeof(int));
But I'd like to avoid anything that excessive (plus it is probably not evaluated at compile time).
Re: Initializing a double to INT_MAX + 1
How about using the compiler constants:
Code:
#include <climits>
void test()
{
double value = static_cast<double>(INT_MAX) + 1;
}
Re: Initializing a double to INT_MAX + 1
Quote:
Originally Posted by
monarch_dodra
Hi,
I'd like to set a double's start value at the maximum possible value a int can hold, +1.
Use the macros/classes defined in <limits.h> or <climits>, not hard-coded values.
Regards,
Paul McKenzie
Re: Initializing a double to INT_MAX + 1
A double is a floating point value, not an integer. You are looking for the 'long' data type, which is the 64 bit version of int, or long long which is 128.
Re: Initializing a double to INT_MAX + 1
Quote:
Originally Posted by ninja9578
You are looking for the 'long' data type, which is the 64 bit version of int, or long long which is 128.
Since monarch_dodra did not provide additional context, it would be presumptuous to assume that an integral type is actually desired over a floating point type. Besides, long is only guaranteed to have a range representable with at least 32 bits and long long (in C99 and the future C++0x) is only guaranteed to have a range representable with at least 64 bits.
EDIT:
By the way, I think that the simplest option may be an implicit cast:
Code:
double value = INT_MAX + 1.0;
Re: Initializing a double to INT_MAX + 1
Hi, thank you for your responses.
Quote:
Originally Posted by
laserlight
Since monarch_dodra did not provide additional context, it would be presumptuous to assume that an integral type is actually desired over a floating point type.
I do need floating point numbers. I am writing a BigInt class, and I needed doubles for a getDouble() method. Basically, I need to write this (simplified code):
Code:
double baseValue = INT_MAX + 1
double currentBaseValue = 1;
double returnValue;
for (int i = 0; i < _units.size(); ++i)
{
returnValue += _units[i] * currentBaseValue;
currentBaseValue *= baseValue;
}
returnn returnValue;
Where _units is a vector of unsigned ints.
I need baseValue to represent "10", in the base "INT_MAX + 1"... if you understand what I am saying.
Code:
static_cast<double>(INT_MAX) + 1;
INT_MAX + 1.0
These two things work, but I am a bit afraid of casting to double before adding the 1. This poses no problem in an environment where int is 32 bits, but I'm not sure it is 100% accurate with 64 bit integers.
I found this solution:
Code:
double a = 0x100000000ULL
or
double a = 1ULL + INT_MAX
I can use an unsigned long long, to get the exact value before casting. This works, but since I want my class templatable, I will also need to write "double a = 1 + U_LONG_LONG_MAX", and that wouldn't work.
So here are my two questions:
1 - Should I be afraid of casting to double before summing the 1?
2 - Since I know the exact binary representation of my double (or at least the value and exponential) can I write something like:
double a = (hex)1e20
where e represents the binary exponent (ie 1*2^32)
Re: Initializing a double to INT_MAX + 1
Quote:
Originally Posted by
monarch_dodra
These two things work, but I am a bit afraid of casting to double before adding the 1. This poses no problem in an environment where int is 32 bits, but I'm not sure it is 100% accurate with 64 bit integers.
To a certain extent, you're screwed anyway at that point. The double only has 52 bits of mantissa; once you're dealing with values larger than 2^52, a double can't be accurate to the 1s place anyway.
While it's certainly true that adding small numbers to big ones in floating point is a bad idea, in this *particular* case I'm not sure it's worth worrying about.
Re: Initializing a double to INT_MAX + 1
Quote:
These two things work, but I am a bit afraid of casting to double before adding the 1. This poses no problem in an environment where int is 32 bits, but I'm not sure it is 100% accurate with 64 bit integers.
If you don't do the cast (either implicitly or explicitly), INT_MAX + 1 is going to overflow and become INT_MIN.... which is definetly not what you want. ;)
Re: Initializing a double to INT_MAX + 1
Quote:
Originally Posted by
Speedo
If you don't do the cast (either implicitly or explicitly), INT_MAX + 1 is going to overflow and become INT_MIN.... which is definitely not what you want. ;)
Very true. Actually, I will use UINT_MAX, and if I don't cast I will get 0
Quote:
Originally Posted by
Lindley
To a certain extent, you're screwed anyway at that point. The double only has 52 bits of mantissa; once you're dealing with values larger than 2^52, a double can't be accurate to the 1s place anyway.
While it's certainly true that adding small numbers to big ones in floating point is a bad idea, in this *particular* case I'm not sure it's worth worrying about.
Not 100% true. Technically, and double can give the EXACT value of numbers like 2^300, which is exactly what I'm trying to do. However, I get your point.
The way I see it, If my ints are 32 bits, then the double will have enough bits for exact representation.
If my ints are 64 bits, then I'm pretty sure that the +1 will do nothing to the double, but that is okay, because UINT_MAX will be rounded off to UINT_MAX+1 (wich is 2^64), giving me exact values anyways.
Thankyou everyone for your input, I think I found my solution.