Kotlin Language

I numeri

Essendo cugino abbastanza prossimo di Java il type system di Kotlin deve per forza avere molte somiglianze con quello del suo più noto parente. Questo avviene anche per i numeri. Tuttavia non bisogna abbassare la guardia.
Kotlin ammette i seguenti tipi di numeri:

Tabella 3.1  
Tipo Ampiezza
Double 64 bit - con virgola
Float 32 bit- con virgola
Long 64 bit
Int 32 bit
Short 16 bit
Byte 8 bit

Non ci sono particolarità eclatanti rispetto ad altri linguaggi, sui può notare come non sia compreso il tipo carattere. Come da documentazione ufficiale vediamo le cose più ovvie:
  • i long sono suffissati da L (maiuscola). Es. 230L
  • Gli esadecimali hanno prefisso 0x
  • i binari hanno prefisso 0b
  • Non c'è supporto per gli ottali
  • I numeri con virgola sono double di default
  • i float hanno suffisso F oppure f
  • Gli interi li sappiamo ovviamente rappresentare i numeri con virgola possono comparirre nel loro formato naturale, ad es 1.234 o esponenziale 1234e10
Fin qui è tutto molto semplice. I problemi nascono, come in molti altri linguaggi, proseguendo nell'esplorazione delle peculiarità del linguaggio ad esempio dal fatto che non sono presenti conversioni implicite. Questo può dare origine a qualche piccolo grattacapo:

val x1: Byte = 5
val x2: Int = x1

dà origine ad errore:

Type mismatch: inferred type is kotlin.Byte but kotlin.Int was expected

Analogamente:

var x1: Byte = 5
x1 = x1 + 10000
println(x1)

non funziona e anche qui l'errore è identico; questo in quanto c'è una conversione interna a int per effettuare la somma e questo non è permesso. La stessa cosa comunque viene segnalata se cercate di assegnare un valore fuori range. Per espandere la magnitudo dei numeri è necessario ricorrere a conversioni esplicite; quelle previste in Kotlin vengono espresse nella tabella seguente:

Tabella 3.2  
Conversione target
toByte() Byte
toShort Short
toInt() Intero
toLong() Long
toFloat() Float
toDouble() Double
toChar() Char

Questi metodi sono disponibili per tutte le tipologie di numero e ci aiutano ad esempio a risolvere casi come quello precedente:

var x1: Byte = 5
x1 = (x1 + 10000).toByte()
println(x1)

In questi casi ovviamente dovete tenere presente la possibilità di risultati "assurdi", ovviamente solo in apparenza, ad esempio se eseguite il frammento precedente vi salta fuori come risultato il numero 21 che potrebbe non essere proprio quanto vi aspettavate (molti di voi sapranno la soluzione, per chi è in dubbio lascio un indizio: (10000 + 5) / 256 ... e pensateci su).
Se volete conoscere i range per i vari tipi, vi vengono offerte le costanti MAX_VALUE e MIN_VALUE, anche in questo caso per ogni tipo:

println(Int.MAX_VALUE)
println(Float.MIN_VALUE)

Le operazioni di base sono le solite:

  Esempio 3.1
1
2
3
4
5
6
7
8
9
10
fun main(args : Array<String>)
{
  var x1 = 7
  var x2 = 3
  println(x2 + x1)
  println(x1 - x2)
  println(x1 * x2)
  println(x1 / x2)
  println(x1 % x2)
}

Le ultime due righe, come è facile verificare, sono rispettivamente la divisione e il resto della divisione. Vi chiederete forse, io lo faccio sempre, come si fa per avere il risultato "vero" della divisione, perchè 7/3 non fa 2 ma 2,33333... un metodo sicuro è quello di usare toFloat o toDouble, quest'ultimo se volete avere maggior precisione, su almeno uno dei due elementi, dividendo o divisore:

println(x1.toDouble() / x2)
println(x1 / x2.toFloat())

Sugli interi e sui long è possibile effettuare le classiche operazioni logiche. Esse, diversamente da quanto avviene in Java, sono introdotte da operatori "letterali" e non dai soliti simboli. Vediamo la tabella:

Tabella 3.3  
Operatore Descrizione
shl bits Shift a sinistra con segno
shr bits Shift a destra con segno
ushr bits Shift a destra senza segno
and bits bitwise and
or bits bitwise or
xor bits bitwise xor
inv() inversione bit a bit

Attenzione alla sintassi, che non è univoca, ad esempio inv si comporta diversamente dagli altri:

var x1 = 1
var x2 = 4
println(x1 shl 2)
println(x2 shr 1)
println(x2.inv())


La libreria
Math, presente quando installate il framework Java, è un eccellente compagno di ogni programmatore in quanto contiene molte funzioni utili pronte all'uso. Potete utilizzarle facilmente (dopo esservi documentati sul loro funzionamento...) anche in Kotlin, con una sintassi molto semplice:

var x1 = 7
var x2 = 3
println(Math.max(x1,x2))
println(Math.pow(x1.toDouble(),x2.toDouble()))