double to unsigned int / char

c++, floating-point, unsigned

Solution

Yes, the same rule applies for C++. (However, I am going by a 2010 draft of the C++ standard; C++ 2003 is old. Also, I am using N3092, not the official draft.) Clause 4.9, paragraph 1 says “The behavior is undefined if the truncated value cannot be represented in the destination type.”

Unsigned integer arithmetic does wrap; it is performed modulo 1 more than the maximum value of the type. However, this applies to arithmetic within the type. Conversion from floating-point to unsigned integer is not part of this.

Your code for converting `d2` seems more complicated than necessary. If `d2` is within the range of an `int`, you could simply use `unsigned char c2 = (int) d2;`. (Although conversion from `int` to `unsigned int` is also outside homogeneous unsigned integer arithmetic, the specification for this conversion does say it is reduced the same way unsigned integer arithmetic is.)

Problem

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 ? ```

Original source

Related problems