This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

unexpected results in integer arithmetics

Hello experts,

to avoid a division, I use integer arithmetics. The unsigned int x which is in the range of 2000 is first multiplied by a number s which is 2048 plus/minus 1000 and then shifted by 11 digits which should replace a division by 2048.

unsigned int  near x;
unsigned int  s

 x = ( (unsigned long) x * (unsigned long) s ) >> 11 ;

For testing I used s=2048. The result should be (x*2048)>>11 = x, but what I get as a result is about 30 times too big, and all results for different values of x are multiples of 0x20.

Type casting problem?

Please help, I run out of ideas.

Parents
  • Hello,
    I tried this on my system and the results were fine. The assembly code is;

    
    s is assigned to R5
    x is assigned to R4
    
     MOV   R5, DPP2:s
     MOV   R4, DPP2:x
    
     MULU  R4, R5          ;x*s
     MOV   R5, MDH
     MOV   R4, MDL
     MOV   R6, R5
     SHR   R4, #0x0B       ;>>11 (32-bit)
     SHL   R6, #0x05
     OR    R4, R6
     MOV   DPP2:x, R4
    

    This is pretty good code except for the extraneous loading of R5 from MDH. Turn on the assembly code option in the listing tab of the project settings and see what you get.

    Best Luck
    Scott


Reply
  • Hello,
    I tried this on my system and the results were fine. The assembly code is;

    
    s is assigned to R5
    x is assigned to R4
    
     MOV   R5, DPP2:s
     MOV   R4, DPP2:x
    
     MULU  R4, R5          ;x*s
     MOV   R5, MDH
     MOV   R4, MDL
     MOV   R6, R5
     SHR   R4, #0x0B       ;>>11 (32-bit)
     SHL   R6, #0x05
     OR    R4, R6
     MOV   DPP2:x, R4
    

    This is pretty good code except for the extraneous loading of R5 from MDH. Turn on the assembly code option in the listing tab of the project settings and see what you get.

    Best Luck
    Scott


Children
  • Guenther,

    The line looked ok to me.

    I wonder if the fact that one variable is explicitly set as a near (and I presume the other is a far) is the problem. Perhaps making all variables far would help.

  • Mark and John,

    Thanks for a quite interesting discussion. I guess this just goes to show that coding preferences once set will probably never change. Once a path has been chosen, nobody likes to admit that it was the wrong one.

    My own view on this is to dumb down the code as much as humanly possible. I always use parentheses for everything. Since I occasionally work with other peoples code, I keep a printed list of operators and their precedence right above my monitor. I don't have the precedence memorized but I can find out in a second or two. Basically, I want to use C as a tool, I don't want to think about C... I want to think about the system I am implementing. I try to make my code as readable as possible. It is second only to functionality in importance to me. Here is an example of how I use parentheses:

       /* Update the current station button pressed from hardware if a comms
          device doesn't have it pressed */
       if ( (m_bStatButtonPressed == NO_STATION)
            ||
            ( (m_bStatButtonPressed != NO_STATION) &&
              (m_bStatButtonSource == i_bCommAddress()) ) 
            &&
              (m_bStatButtonSlavesUpdated >= i_bTotalCommSlaves()) )
       {
          BYTE bIndex;
          BYTE bStatIndex;
    
    

    To be honest, I beleive that judicious use of white space is every bit as important as parentheses..... it tells the reader what the writer INTENDED to do. I don't consider myself the brightest programmer out there. Because of my limitations, I do everything I can to simplify. If a novice programmer can take over maintenance of my project without having to ask me many questions, I consider the project extremely successful.

  • Meanwhile, back at the ranch, did Guenter ever get his integer math to work?

  • yes, now finally it works.
    The compiler worked correctly, and the type casting does what I expected, but...
    one of the variables was at an address where there was no physical memory.
    After that became clear, the solution was easy.

    Thanks to everyone for your comments on my problem.