Provavelmente você está dividindo dois números inteiros e guardando o resultado em um float, por isso p
vira 1.0
.
Solução: converta qualquer um dos valores da divisão para float utilizando um cast.
float p = (float) img.getHeight() / d.height;
ou
float p = img.getHeight() / (float) d.height;
Explicação:
Existe um conceito chamado de Coerção de tipo em algumas linguages de programação, e é o caso do Java. Nesse caso da divivisão, funciona assim: Quando você utiliza o operador /
, basicamente você está chamando uma função para dividir dois números. O compilador infere qual sobrecarga da função você irá utilizar, baseado nos dois argumentos (o número na esquerda e o número na direita).
Se você faz int / int
, existe uma função que faz essa divisão. O mesmo ocorre para float / float
. Mas e quando misturamos int / float
ou float / int
? Precisamos ter uma função para cada divisão? E quando entrar long
, double
, e todos os outros primitivos? E quando a Oracle adicionar mais um tipo primitivo numérico? A quantidade de combinações de sobrecargas necessárias da função de divisão é absurda. Por isso, utiliza-se coerção, que é converter implicitamente de um tipo para outro mais abrangente, sem perda de dados.
Quando utilizamos int / float
ou float / int
, o int
é convertido para float
, e então pode-se utilizar a função pronta de float / float
. O mesmo acontece para os outros primitivos numéricos (não lembro se char
também entra, eu acho que sim).
Nesse teu exemplo, (acredito que) você tá simplesmente dividindo dois int
s e guardando-os em um float
. A divisão inteira, como diz o próprio nome, não guarda a precisão de ponto flutuante. O resultado da divisão nesse caso é 1.6438356164
, porém a divisão inteira trunca o número e retorna 1
, int
, que é implicitamente castado para float
, pois não há perda de precisão de int
para float
, mais uma coerção.