For a while, I\'ve been representing large powers of 10 in constants using scientific notation, just so I don\'t have to count the zeros. e.g.
#define DELAY_USE
You ask specifically about powers of ten. 1e6
will be exactly one million. You can go up to 1e22
without anything bad happening. However, note that in both C++ and C, 1e6
is a double
constant, rather than an integer constant.
Negative powers of ten are a different story. 1e-1
is inexact, as are all lower powers.
You want to use user defined literals:
constexpr long long operator "" _k(long long l) {
return l * 1000;
}
constexpr long long operator "" _m(long long l) {
return l * 1000 * 1000;
}
then you can simple do:
long long delay = 1_m;
long long wait = 45_k;
You'll never get rounding errors on something less than INT_MAX
, since the specification for double
sets aside 52 bits for you to use. Your "fractional component" is just your integer, and your "exponent" will be 1, and floating point doesn't struggle with that.
In theory, no. Neither language specifies how floating point values are represented, or which values can be represented exactly. (UPDATE: apparently, C11 does recommend a representation. C++, and older C dialects, don't).
In practice, yes, for quite a large range of values. Any implementation you're remotely likely to encounter will use a 64-bit IEEE representation for double
. This can represent any integer value up to 253 (approximately 9x1015) exactly. It can certainly represent anything representable by a 32-bit integer type.
It's really not safe because the compiler will consider it as a floating point number, so the precision is limited to 53 bits instead of 64 bits of integers (long int) for more you can read about the presentation of floating point numbrers
http://en.wikipedia.org/wiki/Floating_point
It seems that gcc
assumes a constant defined using scientific notation as a floating point number unless it is cast.
A simple C code shows this:
#include <stdio.h>
#define DELAY_USEC_FP 1e6
#define DELAY_USEC_INT (unsigned int) 1e6
int main()
{
printf("DELAY_USEC_FP: %f\n", DELAY_USEC_FP);
printf("DELAY_USEC_INT: %u\n", DELAY_USEC_INT);
return 0;
}
On a x86-64 machine, gcc
generates this assembly code ($ gcc -S define.c
):
[...]
; 0x4696837146684686336 = 1e6 in double-precision FP IEEE-754 format
movabsq $4696837146684686336, %rax
[...]
call printf
movl $1000000, %esi
[...]
call printf
movl $0, %eax
As stated here, 10e15 and 10e22 are the maximum power of ten numbers that have an exact representation in simple and double-precision floating-point format, respectively.
Larger power of ten numbers can not be represented using 32-bit or 64-bit integer types.