Pages: [1]   Go Down
Author Topic: Problemi di conversione tra data types  (Read 410 times)
0 Members and 1 Guest are viewing this topic.
Livorno
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho fatto questa funzioncina che converte l'ora (data da 3 numeri distinti, ora, minuti, secondi) in secondi:

Code:
unsigned long OraMinutiSecondiInSecondi (byte h, byte m, byte s) //Converte l'orario in secondi (da 0 a 86399 sec)
{
return h * 60 * 60 + m * 60 + s;
}

Concettualmente è giusta, ma in pratica mi da un risultato errato. Ho scoperto che il problema è causato dal calcolo che viene fatto tra data type differenti. Ho quindi modificato il codice in questo modo, ma mi chiedo se è corretto o meno:
Code:
unsigned long OraMinutiSecondiInSecondi (byte h, byte m, byte s) //Converte l'orario in secondi (da 0 a 86399 sec)
{
return (unsigned long)h * 60 * 60 + (unsigned long)m * 60 + (unsigned long)s;
}

Avrei potuto mettere direttamente gli unsigned long in questo modo, evitando di doverli convertire con il cast?:
Code:
unsigned long OraMinutiSecondiInSecondi (unsigned long h, unsigned long m, unsigned long s) //Converte l'orario in secondi (da 0 a 86399 sec)
{
return h * 60 * 60 + m * 60 + s;
}

Funzionano entrambe, ma qual'è la soluzione migliore? Tra le 2 direi la prima perchè così si evita di dover dichiarare delle variabili che occupano più memoria, ma anche la prima non so se è corretto fare così o se ci sono altre soluzioni.
Logged

0
Offline Offline
Shannon Member
****
Karma: 117
Posts: 10106
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

la seconda è più corretta.
La prima ti nasconde il fatto che quando fai il casting, oltre a rimanere in memoria le 3 variabili in byte ce le hai anche in unsigned long. con la seconda invece hai solo 3 unsigned long.

poi per risparmiare qualche calcolo all'arduino puoi indicare i numeri come long, altrimenti lui li prende come interi e poi fa un cast in automatico (che ruba cpu)
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Perché non hai messo
Code:
h*3600
? Risparmi 1 moltiplicazione.
Logged


Livorno
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

la seconda è più corretta.
La prima ti nasconde il fatto che quando fai il casting, oltre a rimanere in memoria le 3 variabili in byte ce le hai anche in unsigned long. con la seconda invece hai solo 3 unsigned long.

poi per risparmiare qualche calcolo all'arduino puoi indicare i numeri come long, altrimenti lui li prende come interi e poi fa un cast in automatico (che ruba cpu)
Potresti aggiungere qualche dettaglio per favore? Mi interessa la cosa.
Cioè in pratica in ogni caso alla fine della funzione, una volta che questa fa la return al loop principale, le variabili rimangono tutte in memoria?
Ad ogni modo io pensavo che la prima fosse meglio perchè al di fuori della funzione stessa devo comunque dichiarare delle variabili ed in questo caso sarebbero 3 byte anzichè 3 unsigned long.
Logged

0
Offline Offline
Shannon Member
****
Karma: 117
Posts: 10106
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

no, il cast automatico fa nascere e morire le variabili nella chiamata stessa (o meglio nel blocco che è raèresentato dalla chiamata), altrimenti sarebbe un bel problema, non trovi?
dovresti ripassarti la "visibilità delle variabili" http://it.wikipedia.org/wiki/Variabile_%28informatica%29#Visibilit.C3.A0_di_una_variabile

Se usi la seconda, puoi comunque usare i byte nella funzione chiamte/globalmente, quando chiami la funzione dandogli i byte dovrebbero essere automaticamente castati in unsigned long.
Il punto è che quando chiami una funzione passandogli degli argomenti per valore, vengono duplicati.

quindi col primo metodo avresti:
3 byte globali/della chiamante
3 byte copiati per il passaggio di valore
3 unsigned long per la moltiplicazione

invece col secondo metodo hai:
3 byte globali/della chiamante
3 unsigned long per la moltiplicazione che ti arrivano dal passaggio per valore con autocast

con un risparmio, solo nell'ambito della chiamata stessa, di 3 byte
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Livorno
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perché non hai messo
Code:
h*3600
? Risparmi 1 moltiplicazione.
Giusto smiley
Logged

Livorno
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Forse ho capito...
Ma non ho capito, in ogni caso alla fine dell'esecuzione della funzione mi ritrovo la memoria liberata o no?

Voglio dire, nel programma principale dichiaro 3 variabili dove memorizzo ore, minuti, secondi, poi questi li passo alla funzione che me li converte in secondi e mi restituisce un numero che me lo salvo in un'altra variabile dedicata.
Tutte le altre variabili usate all'interno della funzione (siano esse più o meno sprecate) vengono poi eliminate giusto?
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Si tratta di capire lo spazio dei nomi, ossia la sezione del programma in cui una variabile è visibile.
Se dichiari una variabile globale, ossia la metti in cima al programma, fuori da setup() e loop(), essa sarà visibile a qualsiasi funzione dello sketch ma non sarà mai distrutta: verrà creata all'avvio e rimarrà in vita per tutta la durata dell'esecuzione del codice (vale a dire finché non toglierai l'alimentazione).

Se invece crei una variabile locale, essa sarà visibile solo all'interno della funzione in cui è stata creata e "vivrà" con essa: sarà creata nel momento in cui chiami la funzione, e verrà distrutta nel momento in cui esci da quella funzione.

Ecco perché, ad esempio, puoi dichiarare "int i" come variabile temporanea in tutte le funzioni del tuo programma senza paura che "i" di, diciamo, funzione_xxx non potrà mai essere confusa con "i" di funzione_yyy.
Logged


Livorno
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perfetto,
grazie
Logged

Pages: [1]   Go Up
Jump to: