
In realtà l’errore che viene commesso non è di carattere informatico, ma puramente matematico, dimenticando l’ordine con cui vengono eseguite le operazioni matematiche.
L’ordine delle operazioni segue le regole di base: moltiplicazioni e divisioni hanno precedenza massima seguono addizioni e sottrazioni. Se si vuole cambiare l’ordine di precedenza bisogna utilizzare le parentesi. Vediamo alcuni esempi.
1 | int valore = 1 + 2 * 3 + 4; |
il risultato sarà 11.
6 | bool abilitaMessaggio = 0; |
16 | if (abilitaMessaggio == 0) { |
19 | Serial.println( "Calcolo:" ); |
20 | Serial.println( "valore = 1 + 2 * 3 + 4" ); |
21 | int valore = 1 + 2 * 3 + 4; |
22 | Serial.print( "valore = " ); |
23 | Serial.println(valore); |

Per rendere più evidente la sequenza di esecuzione del calcolo possiamo usare le parentesi, pertanto otterremo:
1 | int valore = 1 + (2 * 3) + 4; |
Che fornisce sempre il valore 11.
6 | bool abilitaMessaggio = 0; |
16 | if (abilitaMessaggio == 0) { |
19 | Serial.println( "Calcolo:" ); |
20 | Serial.println( "valore = 1 + (2 * 3) + 4" ); |
21 | int valore = 1 + (2 * 3) + 4; |
22 | Serial.print( "valore = " ); |
23 | Serial.println(valore); |

Per modificare la precedenza utilizziamo le parentesi:
1 | int valore = ((1 + 2) * 3) + 4; |
il risultato sarà 13. Viene eseguito prima il calcolo della parentesi più interna (1+2), poi si passa alla parentesi immediatamente successiva, quindi (3 * 3) e poi il risultato viene sommato a 4.
6 | bool abilitaMessaggio = 0; |
16 | if (abilitaMessaggio == 0) { |
19 | Serial.println( "Calcolo:" ); |
20 | Serial.println( "valore = ((1 + 2) * 3) + 4" ); |
21 | int valore = ((1 + 2) * 3) + 4; |
22 | Serial.print( "valore = " ); |
23 | Serial.println(valore); |

Ovviamente, come già spiegato precedentemente, bisognerà sempre fare attenzione che il risultato faccia parte del tipo di dati giusto, ad esempio quando effettuate una divisione tra interi il cui risultato è un numero decimale, o ancora se superate il valore massimo del tipo di dato che state utilizzando. In entrambi i casi il compilatore non vi segnalerà nessun errore.
Vediamo un esempio:
2 | long secondi_in_un_giorno = 60 * 60 * 24; |
In teoria, poiché il risultato è 86.400, questo valore potrà essere contenuto in un tipo long.
Ma in realtà il valore realmente memorizzato in “secondi_in_un_giorno” è 20.864.
86.400 supera più di due volte la dimensione di un intero, il calcolo fatto dal compilatore sarà il seguente:
86.400 – 32.768 * 2 = 20.864
7 | bool abilitaMessaggio = 0; |
17 | if (abilitaMessaggio == 0) { |
20 | Serial.println( "Calcolo (errato) numero di secondi in un giorno:" ); |
21 | Serial.println( "secondi_in_un_giorno = 60 * 60 * 24" ); |
22 | long secondi_in_un_giorno = 60 * 60 * 24; |
23 | Serial.print( "Secondi in un giorno = " ); |
24 | Serial.println(secondi_in_un_giorno); |
25 | Serial.println( "Errore! Il valore doveva essere: 86.400" ); |
26 | Serial.println( "L'errore si verifica perchè il compilatore considera i numeri di tipo int." ); |

Ciò accade perché il compilatore C dell’IDE di Arduino vede un’espressione aritmetica composta da soli numeri interi e quindi considera il risultato come tipo int. Per evitare questo problema bisogna dire al compilatore che deve trattare l’intera espressione come un long aggiungendo L al primo valore che viene valutato nell’espressione:
1 | long secondi_in_un_giorno = 60L * 60 * 24; |
7 | bool abilitaMessaggio = 0; |
17 | if (abilitaMessaggio == 0) { |
20 | Serial.println( "Calcolo corretto del numero di secondi in un giorno:" ); |
21 | Serial.println( "secondi_in_un_giorno = 60L * 60 * 24" ); |
22 | long secondi_in_un_giorno = 60L * 60 * 24; |
23 | Serial.print( "Secondi in un giorno = " ); |
24 | Serial.println(secondi_in_un_giorno); |
25 | Serial.println( "Giusto! Abbiamo detto con la L che l'intera espressione è da trattate come un long." ); |

Attenzione sempre alle parentesi!
Se le utilizzate ad esempio come nell’esempio che segue farà andare in overflow il risultato:
1 | long secondi_in_un_giorno_piu_uno = 1L + 60 * (60 * 24); |
7 | bool abilitaMessaggio = 0; |
17 | if (abilitaMessaggio == 0) { |
20 | Serial.println( "Calcolo errato somma 1 al numero di secondi in un giorno" ); |
21 | Serial.println( "secondi_in_un_giorno_piu_uno = 1L + 60 * (60 * 24)" ); |
22 | long secondi_in_un_giorno_piu_uno = 1L + 60 * (60 * 24); |
23 | Serial.print( "Secondi in un giorno + 1 = " ); |
24 | Serial.println(secondi_in_un_giorno_piu_uno); |
25 | Serial.println( "Sbagliato! Attenzione sempre alle parentesi!" ); |
26 | Serial.println( "Se le utilizzate ad esempio come indicato farà andare in overflow il risultato" ); |

mentre la seguente espressione non farà andare in overflow il calcolo:
1 | long secondi_in_un_giorno_piu_uno = 1 + 60 * (60L * 24); |
8 | bool abilitaMessaggio = 0; |
18 | if (abilitaMessaggio == 0) { |
21 | Serial.println( "Calcolo errato somma 1 al numero di secondi in un giorno" ); |
22 | Serial.println( "secondi_in_un_giorno_piu_uno = 1 + 60 * (60L * 24)" ); |
23 | long secondi_in_un_giorno_piu_uno = 1 + 60 * (60L * 24); |
24 | Serial.print( "Secondi in un giorno + 1 = " ); |
25 | Serial.println(secondi_in_un_giorno_piu_uno); |
26 | Serial.println( "Corretto! Il calcolo inizierà dalle parentesi tonde." ); |
27 | Serial.println( "E' stata aggiunta la L al primo operando tra le parentesi tonde." ); |

Buon Coding a tutti 