I read here, that:
According to C99 §6.3.1.4 footnote 50:
The remaindering operation performed when a value of integer type is converted to unsigned type need not be performed when a value of real floating type is converted to unsigned type. Thus, the range of portable real floating values is (−1, Utype_MAX+1).
Now, I am interested in the subtle difference (this time for C++ 03!) between:
double d1 = 257;
double d2 = -2;
unsigned char c1 = d1; // undefined, since d1 > 256
unsigned char c2 = d2; // undefined, since d2 < -1
and
double d1 = 257;
double d2 = -2;
unsigned int i1 = d1; // defined, since d1 <= 2^32
unsigned int i2 = d2; // still undefined, right?
unsigned char c1 = i1; // defined, modulo 2^8, so c1 == 1
So the first c1
and the second c1
are not guaranteed to compare as equal, right? Is the citation from above also valid for C++03, or are there other rules?
Edit:
and for making c2
defined (for -(2^31-1) <= d2 < 0
) would this be necessary to do?
double d2 = -2;
int sign = (d2<0 ? -1 : 1);
unsigned char c2 = sign * (int)abs(d2); // defined, c2 == 2^8-2 ?