A regra do casting é simples. Você sempre precisará fazer cast de um tipo mais preciso para um menos preciso.
Ou seja:
long -> int -> short -> byte
ou de um tipo com casa decimal para um sem casa decimal:
double -> long, int, short ou byte
float -> long, int, short ou byte
Isso porque nesse tipo de conversão existe chance de você perder dados. Aí ocorre coisas esquisitas como essa aqui:
http://www.guj.com.br/posts/list/98657.java
No sentindo inverso, não há necessidade de conversão. Afinal, você não perde dados tornando sua variável mais precisa.
Quanto a somas, qual é a sua dúvida?
Você pode fazer soma normalmente:
int x = 10 + 5;
int y = x + x;
int z = (y * 2) / x;
Tome cuidado com os tipos literais. Por exemplo, o valor 10, na equação acima é do tipo inteiro. O java é esperto o suficiente para te poupar do cast em atribuições diretas:
byte x = 10; //Ok, ao invés de inteiro, esse 10 é byte mesmo.
Quando uma expressão mistura mais de um tipo, o cast é feito aumaticamente para o tipo mais preciso. Se houver um número de ponto flutuante (double ou float), o cast é feito para o tipo de ponto flutuante.
Tome cuidado que o simples fato de você dividir não provoca casts. Então, a conta abaixo pode causar surpresa em alguns iniciantes:
double x = 9 / 2;
System.out.println(x); //Imprime 4.0
9 é inteiro. 2 é inteiro. Não houve cast no resultado e, por ser inteiro, perdeu as casas demais. Contas de inteiros são admitidas pela linguagem. Para contornar o problema, faça o seguinte:
double x = 9.0 / 2; //Agora 9 é um double. 2 será promovido para double e o resultado será double.
Ou:
double x = 9 / 2.0; //Agora 2 é um double. 9 será promovido para double e o resultado será double.
Ou ainda:
double x = 9.0 / 2.0; //Ok, ambos double. Resultado double.
Cara, não entendi. Qual é o seu problema com o for e com o while?