Slide 9 de 74

Aritmética nas bordas

proc main(): void {
	echo 1 / 0          // 0 — divisão por zero é um valor, não uma falha
	echo 1.0 / 0.0      // 0
	echo 5 % 0          // 0
	echo -7 % 3         // -1 — o resto toma o sinal do que é dividido
	echo 7.5 % 2.0      // 1.5

	top := 9223372036854775807
	echo top + 1        // 9223372036854775807 — um Int fica na borda
	echo -top - 10      // -9223372036854775808 — em qualquer das bordas
	echo 2 ** 100       // 9223372036854775807
	echo 2 ** -1        // 0 — um expoente Int negativo não tem resposta inteira
	echo 10.0 ** 400.0  // +Inf — a aritmética de Float chega ao infinito
}

A maior parte da aritmética não surpreende. Estes são os casos que vale a pena conhecer com exatidão, e o que têm em comum é que cada um é um valor, e não uma falha:

  • Dividir por zero, ou tirar o resto por zero, responde com 0 — tanto para um Int quanto para um Float.
  • Um Int nunca dá a volta. Uma soma, diferença, produto ou potência que passaria do maior Int, 9223372036854775807, fica nele, e uma que passaria do menor, -9223372036854775808, fica nesse: um contador que chega ao topo fica lá, por mais que se some. Negar o menor Int dá o maior, que é o mais próximo que ele tem.
  • ** sobre Ints é multiplicação repetida, então 2 ** 100 também chega ao topo. Um expoente negativo não tem resposta inteira, então dá 0, e n ** 0 é 1.
  • Um resto toma o sinal do número dividido, então -7 % 3 é -1, e % funciona com Floats.
  • A aritmética de Float chega ao infinito: 10.0 ** 400.0 é +Inf. Para a resposta real de uma potência, trabalhe em Float, onde ** é exponenciação de verdade.

Um caso na linguagem inteira fica sem especificação: transformar em Int um Float infinito, não numérico ou grande demais para um Int, com hive.conv.ceil, floor ou round. Confira a faixa antes, se isso importar.