If duty
is an integer, then duty / 100
will be the integer quotient, i.e. truncated to an integer, which will be zero for duty
< 100. The computationally cheapest way to avoid this is performing the multiplication first, like
register = duty * timer_top / 100;
If you want to do real floating-point division, you can write that as
register = (int) (duty / 100. * timer_top);
where the decimal point in the constant makes it a double value. In this case, you can also use the other alternatives you wrote to affect rounding behaviour. But you can get different rounding behaviour using integer divisions only as well, e.g.
register = (duty*timer_top + 50)/100;
which will round to nearest instead of to zero, just like your + 0.5
would in the double-valued approach.