arithmetic bug when using array on microC 4.60 compiler

General discussion on mikroC.
Post Reply
Author
Message
ronny05
Posts: 4
Joined: 27 Apr 2011 16:25

arithmetic bug when using array on microC 4.60 compiler

#1 Post by ronny05 » 27 Apr 2011 16:55

Hello.

I need to realize an BCD to decimal converter over 8 decimal positions.
i declared an array to receive my keyboard entries (a decimal values like a calculator)
i have to convert it on binary code. To make it easy I decided to use a simply methode
ex 1,2,3,4,5,6,7,8 with BCD to dec8:
dec8= d'12345678' (dec8 must be 87 654 321)

dec8 = 1 * 1 // the result is 1
dec8= dec8 + (2*10)
dec8= dec8+ (3*1000)
...

the problem is when

Code: Select all

int start_array[8]= {1,2,3,4,5,6,7,8} ; 
long int dec8=0;

void main() {
  ANSEL  = 0;                              // Configure AN pins as digital I/O
  ANSELH = 0;

    dec8 += saisie_val[0];                //the result dec8 = 1
    dec8 += saisie_val[1]*10;          //the result dec8 = 21
    dec8 += saisie_val[2]*100;         
    dec8 += saisie_val[3]*1000;      //the result dec8 = 321
    dec8 += saisie_val[4]*10000;     //the result dec8 = 4321
 [color=#FF0040]   dec8 += saisie_val[5]*100000;   //the result dec8 = 214294956081[/color]
    dec8 += saisie_val[6]*1000000;
    dec8 += saisie_val[7]*10000000;
}
how could you expline me why?
Please is there an other method more efficient to convert a BCD code over 8positions to binary code
Thanks a lot.

sasa72
Posts: 89
Joined: 21 Apr 2011 05:21

Re: arithmetic bug when using array on microC 4.60 compiler

#2 Post by sasa72 » 28 Apr 2011 12:17

To be precise, BCD is a compact form for decimal numbers and they goes in pairs in one byte... One BCD digit have 4 bits and binary that is from 0000 to 1001 (0 to 9).

To convert BCD number in decimal value in mikroC, take a look this family of functions: Bcd2Dec*();

Regarding your code, you simply reverse high and low decimal places. Unfortunately, you need a long cast, since compiler will not perform multiplication of two integers and place it in long and probably return truncated overflowed value.

ronny05
Posts: 4
Joined: 27 Apr 2011 16:25

Re: arithmetic bug when using array on microC 4.60 compiler

#3 Post by ronny05 » 29 Apr 2011 20:28

Ikno i had just to swap the places but th probel is not here

The problem is when i arrived at this line:
dec8 += saisie_val[5]*100000;
the result is not what I expected. the resulte have to be : 54321
but when i simulated it, the result of this operation is: 214294956081
it seems to me like a bug. yes/no?

Code: Select all

int start_array[8]= {1,2,3,4,5,6,7,8} ;
long int dec8=0;

void main() {
  ANSEL  = 0;                              // Configure AN pins as digital I/O
  ANSELH = 0;

    dec8 += saisie_val[0];                //the result dec8 = 1
    dec8 += saisie_val[1]*10;          //the result dec8 = 21
    dec8 += saisie_val[2]*100;         
    dec8 += saisie_val[3]*1000;      //the result dec8 = 321
    dec8 += saisie_val[4]*10000;     //the result dec8 = 4321
    dec8 += saisie_val[5]*100000;   //the result dec8 = 214294956081
    dec8 += saisie_val[6]*1000000;
    dec8 += saisie_val[7]*10000000;
}

sasa72
Posts: 89
Joined: 21 Apr 2011 05:21

Re: arithmetic bug when using array on microC 4.60 compiler

#4 Post by sasa72 » 04 May 2011 11:09

It definitely behaves differently than other C compilers. Seems logical that constant 10000 be promoted to long since multiplication with another byte/integer surely exceed integer range.

If force long cast, problem vanished:

Code: Select all

dec8 += saisie_val[4]*(long)10000;     
You can also try this optimized version of your code:

Code: Select all

long dec8=0;
char v[8]= {1,2,3,4,5,6,7,8};

void main() {
  int i = 8;
  
  ANSEL  = 0;
  ANSELH = 0;

  while (i>0, i--) {
    dec8 = (dec8 << 3) + (dec8 << 1);
    dec8 += v[i];
  }
}

ronny05
Posts: 4
Joined: 27 Apr 2011 16:25

Re: arithmetic bug when using array on microC 4.60 compiler

#5 Post by ronny05 » 04 May 2011 19:58

that's OK!
Thanks a lot for you help!

Post Reply

Return to “mikroC General”