When numeric values of various types are combined in a expression, they are subject to the usual arithmetic conversions, which is a set of rules which dictate which operand should be converted and to what type.
These conversions are spelled out in section 6.3.1.8 of the C standard:
Many operators that expect operands of arithmetic type cause
conversions and yield result types in a similar way. The purpose is
to determine a common real type for the operands and result. For the
specified operands, each operand is converted, without change of type
domain, to a type whose corresponding real type is the
common real type. Unless explicitly stated otherwise, the
common real type is also the corresponding real type of the
result, whose type domain is the type domain of the operands
if they are the same, and complex otherwise. This pattern is
called the usual arithmetic conversions :
- First, if the corresponding real type of either operand is long double , the other operand is converted, without change of type domain, to a type whose corresponding real type is long
double .
- Otherwise, if the corresponding real type of either operand is double , the other operand is converted, without change of type domain, to a type whose corresponding real type is
double .
- Otherwise, if the corresponding real type of either operand is float , the other operand is converted, without change of type domain, to a type whose corresponding real type is
float .
- Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted
operands:
- If both operands have the same type, then no further
conversion is needed.
- Otherwise, if both operands have signed
integer types or both have unsigned integer types, the operand
with the type of lesser integer conversion rank is converted
to the type of the operand with greater rank.
- Otherwise, if the
operand that has unsigned integer type has rank greater or
equal to the rank of the type of the other operand, then
the operand with signed integer type is converted to the type
of the operand with unsigned integer type.
- Otherwise, if the
type of the operand with signed integer type can represent all of the
values of the type of the operand with unsigned integer type, then the
operand with unsigned integer type is converted to the type
of the operand with signed integer type.
- Otherwise, both operands are converted to the unsigned integer type
corresponding to the type of the operand with signed integer type.
Note in particular the paragraph in bold, which is what applies in your case.
The floating point constant 0.5
has type double
, so the value of other operand is converted to type double
, and the result of the multiplication operator *
has type double
. This result is then assigned back to a variable of type uint8_t
, so the double
value is converted to this type for assignment.
So in this case Result
will have the value 100.