Deu zero por causa da ordem em que as coisas foram feitas.
Por causa dos parênteses, primeiro ele faz a conta n1 / n2. Mas como esses dois números são inteiros, o resultado também será um inteiro, e por isso será truncado/arredondado para zero. Depois você faz o cast do zero para float, que também será zero.
Se quer que a conta seja feita corretamente, basta fazer o cast do primeiro valor, que aí o resultado da operação será um float também:
float r = (float) n1 / n2;
Assim, primeiro é feito o cast de n1 para float. Depois, ao dividir um float por um int, o resultado é um float.