Hola buenas tardes, este es uno de esos topics los cuales no tiene sentido pero si una explicacion:
la verdad estan simple y tan absurdo que suceda este error que me frustra demasiado:
tengo este bloque en mi codigo:
// variable declarada
unsigned long doseX=0;
el siguiente error se me presenta en una de mis operaciones el cual no quiero explicar porque seria demasiado largo, lo que les voy a presentar es el mismo error
BLOQUE CON DERBORDAMIENTO:
doseX = ((13)*(10000));
Serial.println(doseX);
en mi impresion tengo esto "4294966224" la variable se me desborda y es absurdo el resultado deberia ser 130 000 y no tiene porque desbordarse
AHORA, si yo añado un cero mas, es decir de "10 000" a "100 000" el resultado ya no se derborda
doseX = ((13)*(100000));
Serial.println(doseX);
tengo en mi impresion "1300000"
Si haces asi, tampoco se desborda
// variable declarada
unsigned long doseX=0;
void setup() {
Serial.begin(9600);
doseX = (unsigned long) 13*10000;
Serial.println(doseX);
}
void loop() {
}
El tema es que tanto 13 como 10000 se pueden representar como enteros. El compilador hace las cuentas de ese modo y claramente se desborda. Pero si agregas el typecast (unsigned long) le dices al compilador que considere la cuenta del tipo unsigned long y entonces corriges el problema.
ok muchas gracias, lo revisare si me funciona dare por resuelto el tema y dejare como consejo de buenas practicas
En realidad hacer el cast de una operación puede también generar un problema, por ejemplo:
doseX = (unsigned long)((13*10000)+1);
da como resultado 4294966225
Lo correcto es utilizar constantes long
doseX = 13L*10000L;
doseX = ((13L*10000L)+1L);
Me corrijo. En este caso al ser unsigned long:
doseX = 13UL*10000UL;
doseX = ((13UL*10000UL)+1UL);
No estoy para nada en desacuerdo con lo expresado por PeterKanTropus sin embargo miren esta curiosidad
doseX = (unsigned long) 13*10000+1;
qué resultado les parece que da?
Pues
130001
Sin embargo
doseX = (unsigned long)((13*10000)+1);
da 4294966225
De modo que los paréntesis parecen ser los responsables, pero no puedo afirmarlo aún.
Haré mas pruebas.
este es el bloque donde tengo los problemas!
for(int i=41; i <= 76; i++){
/******************************SAVE THE FEED ON*****************************/
EEPROM.update(((i-41)+33),frameReceived[i]);
if(countF == 0){
doseX += (unsigned long)(frameReceived[i] * (10000));
countF++;
Serial.println(doseX);
}
else if(countF == 1){
doseX += (unsigned long)(frameReceived[i] * (100));
countF++;
Serial.println(doseX);
}
else if(countF == 2){
doseX += (unsigned long)(frameReceived[i]);
Serial.println(doseX);
dose[p] = doseX;
doseX = 0;
p++;
countF = 0;
}
}
}
estoy resiviendo datos en api mode in xbee, lo que voy capturando en ciertas posiciones lo cancateno haciendo uno suma y multiplicaciones para recorrer los digos, y es ahi donde se me desborda cuando le llega un 0x0D o 13 que es lo miso (13*10000), pero que curioso que solo al multiplicar por 10k sucede eso si añado o quito un 0 ya no se desborda, como ven ya añado (unsigned long) (framereceived *10000; y se sigue desvordando
Muchas gracias por su ayuda, esto fue lo que me ayudo!
if(frameReceived[16] == 'A'){
Serial.println("\n Tabla AM");
for(int i=17; i <= 28; i++){
arrayHour[p] = frameReceived[i];
EEPROM.update((p+9),frameReceived[i]);
/*Save Values beign block 9*/
p++;
}
p = 0;
for(int i=29; i <= 40; i++){
frequency[p] = frameReceived[i];
EEPROM.update((p+21),frameReceived[i]);
/*Save Values begin block 21*/
p++;
}
p = 0;
for(int i=41; i <= 76; i++){
/******************************SAVE THE FEED ON*****************************/
EEPROM.update(((i-41)+33),frameReceived[i]);
if(countF == 0){
doseX += (frameReceived[i] * 10000UL);
countF++;
Serial.println(doseX);
}
else if(countF == 1){
doseX += (frameReceived[i] * 100UL);
countF++;
Serial.println(doseX);
}
else if(countF == 2){
doseX += frameReceived[i];
Serial.println(doseX);
dose[p] = doseX;
doseX = 0;
p++;
countF = 0;
}
}
}
// If the first byte is a 'P' save the information to the PM cycle.
if(frameReceived[16] == 'P'){
p = 12;
Serial.println("\n Tabla PM");
for(int i=17; i <= 28; i++){
arrayHour[p] = frameReceived[i];
/**********save the hour PM from position 69 (12 init + 57 is equal to the new case*/
EEPROM.update((p+57),frameReceived[i]);
p++;
}
p = 12;
for(int i=29; i <= 40; i++){
frequency[p] = frameReceived[i];
EEPROM.update((p+69),frameReceived[i]);
p++;
}
p = 12;
for(int i=41; i <= 76; i++){
EEPROM.update(((i-41)+93),frameReceived[i]);
if(countF == 0){
doseX += (frameReceived[i] * 10000UL);
countF++;
Serial.println(doseX);
}
else if(countF == 1){
doseX += (frameReceived[i] * 100UL);
countF++;
Serial.println(doseX);
}
else if(countF == 2){
doseX += frameReceived[i];
Serial.println(doseX);
dose[p] = doseX;
doseX = 0;
p++;
countF = 0;
}
}
}
Surbyte en ambos casos esto funciona porque
doseX = (unsigned long) 13*10000;
doseX = (unsigned long) 13*10000+1;
Es equivalente a hacer
doseX = ((unsigned long) 13)*10000;
doseX = ((unsigned long) 13)*10000+1;
Es decir, esta haciendo el cast al numero 13, convirtiéndolo en un unsigned long (UL) y el compilador al tener un UL en la cuenta trabaja todo como UL
en cambio
doseX =(unsigned long)(13*10000);
(13*10000)
es el producto de dos integer y en exa el resultado es: 1fbd0. El uno se desborda y queda fbd0, ahora (no se porque ) al intentar meterlo en un UL le agrega FFFF y queda FFFFfbd0 que en decimal es 4294966224.
Jorge, por el motivo que puse mas arriba
doseX += (frameReceived[i] * 10000UL);
esta funcionando porque uno de los términos de la operación es un Unsigned Long (10000UL) y el compilador realiza todos los cálculos con UL, pero es una buena practica tener todos los términos del mismo tipo. En tu caso frameReceived debe devolver un integer, por eso tuviste problemas en un principio. lo correcto seria tener todo como UL
* *doseX += ( (unsigned long) frameReceived[i] * 10000UL);* *
Prueba hacer
* *doseX += ( (unsigned long) frameReceived[i] * 10000);* *
y veras que también funciona
pero no funcionara
* *doseX += (unsigned long)(frameReceived[i] * (10000));* *
Y por cierto, queda claro que no es un desbordamiento absurdo, sino como suele ocurrir un error que se comete por mala interpretación o mal uso del tipo de variable involucrada en las operaciones.