Università Statale di Milano - Dipartimento di Informatica: 5a lezione sul Linguaggio GO (Golang)



Esercizio 1 - Integer Overflow/Underflow

Scrivere un programma che riceve in ingresso da standard input un valore intero e lo salva in una variabile di tipo int (che chiameremo n). Create quindi due variabili n64 (di tipo int64) e n32 (di tipo int32), e copiateci il valore di n. A questo punto incrementate iterativamente n, n32 e n64 e stampate il loro valore dopo ogni incremento.

In questo modo potrete controllare cosa succede quando il valore contenuto in variabili di tipo int, int32, int64 non è più memorizzabile nelle variabili stesse. Riuscite a spiegarlo? Cosa succede se si modifica lo stesso programma al fine di decrementare la variabile anziché incrementarla?

Che cosa succede se si ripete l'esercizio precedente considerando valori float32, float64?

SUGGERIMENTO:

Partite da un valore pari a 2147483640 (questo valore è pari (231- 8)!!!) e fermate il ciclo appena una delle seguenti condizioni diventa vera (notate che nessuna di queste condizioni si dovrebbe avverare se stessimo parlando di numeri appartenenti all’insieme dei numeri interi - indicato in matematica con il simbolo ℤ - o dei numeri reali - indicato in matematica con il simbolo ℝ ):

(n+1) < n

(n32+1) < n32

(n64+1) < n64

Osservate il seguente esempio di esecuzione (in grassetto il numero inserito dall’utente). Notate cosa succede alla variabile di tipo int32

Esempio di esecuzione (in grassetto il valore inserito dall’utente):

>go run esercizio1.go

Inserisci un valore intero:

Soluzione 

package main

import (
"fmt"
"math"
)

func main() {
var n int = int(math.MaxInt64 - 2)
var n64 int64 = math.MaxInt64 - 2
var n32 int32 = math.MaxInt32 - 2
for i := 0; i < 5; i++ {
fmt.Println("+1\nint64", n64)
fmt.Println("int32", n32)
fmt.Println("int", n)
n64++
n32++
n++
}
}


Esercizio 2 - Uguaglianza tra valori float32 e float64

Scrivere un programma che riceve in input un valore x (float64), e calcola la sua radice quadrata che salva in un’altra variabile y (float64).

Il programma controlla se y*y e’ uguale a x e in tal caso stampa la stringa “x uguale a y*y”; se invece y*y è diverso da x, stampa la stringa “x diverso da y*y”.

Esempi d’esecuzione

> go run floatUguali.go

Inserire un valore: 4

4 uguale a 2*2

Inserire un valore double: 10.89

10.89 uguale a 3.3*3.3

Provate a testare il vostro algoritmo con gli stessi valori e con valori contenenti più numeri decimali (ad es.: 75614632527572653765783.76438726782763245726472486). Ottenete sempre lo stesso risultato?? Se non è così perché?

SUGGERIMENTO: avendo un numero predefinito di bit, il calcolo della radice di numeri con tante cifre verrà necessariamente approssimato. Per capire se due numeri reali sono “approssimativamente” (!!) simili usate quindi un confronto del tipo:

math.Abs(y*y -x)<math.Pow10(-10)

se questo confronto risulta vero si può affermare che y*y è uguale a x fino alla decima cifra decimale.

Soluzione:

package main

import (
"fmt"
"math"
)

func main() {
var x float64
fmt.Println("Inserisic un valore reale:")
fmt.Scanln(&x)
y := math.Sqrt(x)
fmt.Println((y*y)==x)
x = 1.00000000001
y = 1.00000000000
fmt.Println(math.Abs(y*y-x)<math.Pow10(-10))
}


Commenti