Autor Tema: ¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO  (Leído 2796 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO
« en: 11 de Septiembre de 2013, 06:17:22 »
Después de romperme la cabeza hasta la desesperación con un firmware que estoy haciendo he logrado recudir el problema a su mínima expresión y cuál no es mi sorpresa al detectar una multiplicación errónea  :shock: :shock: :shock:

Atecedentes: CCS C v.4.140

He realizado esta simple prueba con una más simple aún función:

Código: CSS
  1. void special_function(void){
  2.  
  3.    int8  a = 80;
  4.    int16 b = 0;
  5.    
  6.    b = a * 3;
  7.    
  8.    fprintf(DEBUG,"< a=%u b=%Lu>\r\n",a,b);
  9. }

y el resultado que obtengo es ...

< a=80 b=65520>

La verdad es que alucino en colores y no doy crédito a lo que mis ojos están viendo ... he intentado cualificar las variables pero el resultado sigue igual ...

Código: CSS
  1. (int16) b = (int8) a *  (int8) 3;

¿donde está mi esperado 240 (80*3)?

EDITO: SOLUCIONADO ... he cualifcado las variables de nuevo pero esta vez he metido una de 16 bits en el lado derecho de la operación ...

Código: CSS
  1. (int16) b = (int8) a *  (int16) 3;

Y ahora si obtengo:

< a=80 b=240>

La verdad es que CCS C cada vez se está poniendo mas "delicado" ...  :?
« Última modificación: 11 de Septiembre de 2013, 06:23:54 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: ¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO
« Respuesta #1 en: 11 de Septiembre de 2013, 06:53:11 »
y no te funciona con:

b=(int16)a*3; ??

en realidad te deberia ir bien sin ponerle nada, pero si por ejemplo te saliese un resultado de 16bits multiplicando una variable de 8bits entonces el resultado seria de 8bits y seria erroneo, esto ocurre en la mayoria de compiladores, vamos que en XC de microchip lo debes poner sino resultado erroneo...

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: ¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO
« Respuesta #2 en: 11 de Septiembre de 2013, 17:04:59 »
Después de romperme la cabeza hasta la desesperación con un firmware que estoy haciendo he logrado recudir el problema a su mínima expresión y cuál no es mi sorpresa al detectar una multiplicación errónea  :shock: :shock: :shock:

Atecedentes: CCS C v.4.140

He realizado esta simple prueba con una más simple aún función:

Código: CSS
  1. void special_function(void){
  2.  
  3.    int8  a = 80;
  4.    int16 b = 0;
  5.    
  6.    b = a * 3;
  7.    
  8.    fprintf(DEBUG,"< a=%u b=%Lu>\r\n",a,b);
  9. }

y el resultado que obtengo es ...

< a=80 b=65520>

La verdad es que alucino en colores y no doy crédito a lo que mis ojos están viendo ... he intentado cualificar las variables pero el resultado sigue igual ...

Código: CSS
  1. (int16) b = (int8) a *  (int8) 3;

¿donde está mi esperado 240 (80*3)?

EDITO: SOLUCIONADO ... he cualifcado las variables de nuevo pero esta vez he metido una de 16 bits en el lado derecho de la operación ...

Código: CSS
  1. (int16) b = (int8) a *  (int16) 3;

Y ahora si obtengo:

< a=80 b=240>

La verdad es que CCS C cada vez se está poniendo mas "delicado" ...  :?



CCS y cualquier compilador ANSI haría lo mismo. Normalmente esto se llama promoción a enteros, el estandart dice que todos los operandos menores a enteros ( char, enum, etc ) deben ser promovidos a un entero antes de operar. Esto en un compilador de PC esta barbaro, en un compilador para micros de 8 bits es una locura !!!, debido a la cantidad de código de overhead que genera. Por eso que casi todos los compiladores para micros de 8 bits esta característica es deshabilitada por defecto.  Para manejar este caso, como has hecho, solamente es necesario castear uno de los operandos, nunca el resultado. En el caso de constantes ( define ) es necesario colocar el sufijo U o UL según corresponda ( unsgined o unsigned long )

Saludos !

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: ¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO
« Respuesta #3 en: 11 de Septiembre de 2013, 17:09:55 »
en XC eso no ocurre, mientras no se supere los 8bits >255 no habria problema ya que simplemente haria una multiplicacion de 8bits (a=80) por 8bits (3) y el resultado seria 8bits (240) otra cosa distinta es por ejemplo ponerle 100*3 entonces si saldria un resultado erroneo ya que el byte high no se tocaria y quedaria el byte low multiplicado unicamente.

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: ¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO
« Respuesta #4 en: 11 de Septiembre de 2013, 20:53:45 »
Una preguntita RedPic y si b es un int el resultado te daria 240?

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: ¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO
« Respuesta #5 en: 12 de Septiembre de 2013, 03:25:48 »
Una preguntita RedPic y si b es un int el resultado te daria 240?

Seguramente si, no he hecho la prueba pero el tema está en que da un resultado correcto de 8 bits sobre 16 bits si entre los operando hay al menos uno de ellos de 16 bits.

Quiero probar la solución de MerLiNz que cualifica la operación completa a ver qué tal.

Os comento el resultado  :mrgreen:
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: ¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO
« Respuesta #6 en: 12 de Septiembre de 2013, 11:28:56 »
Hola Diego!

El problema es que cuando haces 80 * 3, esto da un resultado de 240, y eso en un int8 (CON SIGNO) desborda el máximo [-128 a 127] y si bien termina dando el valor binario 240, en un int8 es visto como un -16, que al multiplicarse por 3 pasa a valer -48. El -48 en una variable int16 se almacena como: 65520, que aparece literalmente porque imprimes forzando Lu (SIN SIGNO).

El compilador intenta realizar los cálculos usando el menor posible tamaño de variable (en este caso int8). Necesitas castearlo para poder exigirle al compilador que adapte las variables antes de realizar los cálculos pertinentes.

Saludos
 

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: ¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO
« Respuesta #7 en: 12 de Septiembre de 2013, 14:07:10 »
Que tal amigos!
Ese problema mencionado por RedPic, ya fue resuelto (por lo menos) en la ultima version del CCS!  :mrgreen:

Saludos

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: ¿8, 16 bits?¿Bug?¿Qué estoy haciendo mal? SOLUCIONADO
« Respuesta #8 en: 12 de Septiembre de 2013, 17:19:22 »
Muy cierto lo que dice brunoF no me di cuenta que era signed


 

anything