Your example, unsigned i = -.1;
is well-defined by both C11 and C99, and the result is i == 0
.
Quoted from N1570, 6.3.1.4 Real floating and integer:
- When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e.,
the value is truncated toward zero). If the value of the integral part
cannot be represented by the integer type, the behavior is
undefined.61)
61) 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).
Quoted from N869, 6.3.1.4 Real floating and integer:
#1
When a finite value of real floating type is converted to an integer
type other than _Bool, the fractional part is discarded (i.e., the
value is truncated toward zero). If the value of the integral part
cannot be represented by the integer type, the behavior is
undefined.43)
43)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).
However, as you can see from the quotations, trying to convert floating-point constants outside the range (-1, Utype_MAX+1) invokes undefined behaviour.