a/b
will perform an integer division since they are integral types, which will result in 1
, this explains why std::ceil returns the value you are seeing. if we look at the draft C++ standard section 5.6
Multiplicative operators paragraph 4 says(emphasis mine):
The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded;[...]
casting either of the operands to double will be sufficient due to arithmetic conversions which are covered in section 5
Expressions paragraph 10 which says(emphasis mine):
Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:
and includes this bullet:
Otherwise, if either operand is double, the other shall be converted to double.
So the following expression will yield the result you desire:
std::ceil( double(a)/b)