Multiplication issue PIC16F1934

Discussion in 'Embedded Systems and Microcontrollers' started by Stuntman, Apr 13, 2012.

  1. Stuntman

    Stuntman Thread Starter Member

    Joined:
    Mar 28, 2011
    161
    37
    Perhaps I am overlooking a limitation of this PIC chip, but want to confirm.

    I am compiling with HiTech C.

    I have a routine that multiplies the 8 bit counter (TMR0) by the number 139 (fixed point math for .0139). the LCDwrite function converts to a string and adjusts the decimal place to convert back from the fixed point notation, then outputs the value to my LCD.

    However, although I am setup to do this all in LONG format. The resulting multiplication seems to be of data type INT.

    To exemplify:


    Code ( (Unknown Language)):
    1. long result
    2.  
    3. result=TMR0*139;
    4. LCDwrite(result)
    works fine until I get to a value over 32767, at which point the LCD displays a negative number. However:

    Code ( (Unknown Language)):
    1. long result
    2.  
    3. result=TMR0*139;
    4. result=35306; //(255*139=35306)
    5. LCDwrite(result)
    Will display just fine. Additionally:

    Code ( (Unknown Language)):
    1. long result
    2.  
    3. result=TMR0*100;
    4. result=result+TRM0*39;
    5. LCDwrite(result)
    Fixes the issue.
    I would like to get to the root of this problem so I can avoid it in the future.

    Thank you
     
    #1
  2. MrChips

    MrChips Moderator

    Joined:
    Oct 2, 2009
    11,752
    3,010
    Try converting TMR0 to long first.

    Code ( (Unknown Language)):
    1.  
    2. long result;
    3.  
    4. result = TMR0;
    5. result = result * 139;
    6.  
     
    #2
    Stuntman likes this.
  3. Stuntman

    Stuntman Thread Starter Member

    Joined:
    Mar 28, 2011
    161
    37
    Right on Mr. Chips. (I hadn't even gotten back to MPLAB to tinker before you posted ;))

    I assume that the compiler chooses a multiplication algorithm based on the precision of the multiplicands and not the result?

    Thanks again!
     
    #3
  4. WBahn

    WBahn Moderator

    Joined:
    Mar 31, 2012
    12,677
    3,176
    If it is a compliant compiler, it has to do this. The complier writer is given a lot of flexibility into how expressions are evaluated, but there are a set of fundamental rules that they must adhere to in order to ensure that two compliant compilers will always produce the same result. Among these are the data type promotions that are carried out and when they are carried out.

    Note that your third attempt only appears to fix the problem. If TMR0 were any value greater than 327, the problem would be back.

    Another way to solve the problem would be the following:

    result = TMR0;
    result = result * 139;

    You might also try:

    result = TMR0 * 139L;

    In the first case, you are multiplying a long by an int constant, which produces a long. In the second case, you are multiplying an int by a long constant, which also produces a long.
     
    #4
  5. chrisw1990

    chrisw1990 Active Member

    Joined:
    Oct 22, 2011
    543
    41
    you can also use unsigned long.. =] as long as you dont actually need the minus.. but i would assume you dont by the post
     
    #5
  6. CVMichael

    CVMichael Active Member

    Joined:
    Aug 3, 2007
    416
    17
    Or you can use type casting:
    Code ( (Unknown Language)):
    1.  
    2. long result
    3.  
    4. result=(long)TMR0 * 139;
    5. LCDwrite(result)
    6.  
    The compiler does the multiplication first, and then it assigns the resulting value.
    When it does the multiplication it sees the TMR0 as a byte and value 139 as a signed integer (the default), the result is the largest type, the integer.

    So it does not even "see" the long until it has to assign the result of the multiplication.

    If you change any of TMR0 to a type long, or the 139 to a type long, then it will make the calculation with largest data type.
     
    #6
  7. WBahn

    WBahn Moderator

    Joined:
    Mar 31, 2012
    12,677
    3,176
    So, Stuntman, as you can see there are many ways to skin the cat. The point to focus on is understanding why the cat needs to be skinned in the first place.
     
    #7
  8. MrChips

    MrChips Moderator

    Joined:
    Oct 2, 2009
    11,752
    3,010
    This is a good example why I recommend newcomers to microcontrollers to learn ASM first.
     
    #8
  9. WBahn

    WBahn Moderator

    Joined:
    Mar 31, 2012
    12,677
    3,176
    I completely agree. But in this, as in so many areas of engineering, the current trend is to opt for all the higher level tools right out of the gate so that students can do flashy stuff as quickly as possible with as little effort as possible so as to convince them that engineering isn't as hard as they've always been told it was. I'm a bit cynical on this point, in case it wasn't a tad apparent, but I really do think we have sacrificed too much of the fundamentals and are doing students a disservice. Now, people that got their education in the 60's and 70's almost certainly look at my generation that went to college (the first time, anyway) in the 80's and say the same thing. And my response would be that they are absolutely correct to say it -- I know my education missed a number of fundamental items that were taken for granted a decade or two earlier, but I do think it has accelerated for two (probably more) big reasons: There are fewer opportunities for kids to develop the kind of "first love" for getting their hands dirty (by tearing things apart and getting an inkling of how they might work, instead of seeing a blob of epoxy on a green board) than there used to be, and we simply have a lot more tools and toys that make it possible for people to (appear to) do productive things very quickly because they can let the tools do their thinking for them.

    Okay, I don't want to hijack the thread, so I'll get off my soap box.
     
    #9
  10. MrChips

    MrChips Moderator

    Joined:
    Oct 2, 2009
    11,752
    3,010
    I'm with you. My introduction to computers was by toggling machine code via front panel switches on a DEC PDP/8S and DG NOVA in the early 70s. I don't know if my understanding and passion for microcomputers would have been the same had it not been for that experience.

    I teach this stuff and it is getting more and more difficult to get young people excited about it.
     
    #10
  11. WBahn

    WBahn Moderator

    Joined:
    Mar 31, 2012
    12,677
    3,176
    Oh, and Stuntman, none of my rant (and I suspect Mr. Chips' as well) was directed specifically at you. In fact, I applaud you for asking the question you did in order to get a better understanding, especially since you (thought you) had found a solution to your problem. Too many people are like monkeys at a keyboard and as soon as they find some random way of writing the code the produces the immediately desired answer, will mark the issue resolved and moved on. You didn't -- and good for you!
     
    #11
  12. Stuntman

    Stuntman Thread Starter Member

    Joined:
    Mar 28, 2011
    161
    37
    I appreciate the comprehensive explanation, I did not realize this was a rudimentary concept in C for mcu's.
     
    #12
  13. CVMichael

    CVMichael Active Member

    Joined:
    Aug 3, 2007
    416
    17
    That's basics in C, in general, not just MCUs
     
    #13
  14. WBahn

    WBahn Moderator

    Joined:
    Mar 31, 2012
    12,677
    3,176
    It's not just a rudimentary concept in C for MCUs, it is a rudimentary concept in the C language, period.

    Since code compiled for an integer-only processor (as most MCUs are) has to work under much greater restrictions and suffers much greater penalties for having to emulate things that other processors support natively, I highly recommend becoming familier with the C standard. While you have to buy the actual standard, you can download the draft standard for free from a lot of places and there are very few differences (I'm not aware of any that are of substance, but I could be wrong). It is a big document and can be intimidating, so take it in chunks. Use it to explore specific issues and questions, first. There are a lot of things there, especially in the early material, that will be hard to wrap your mind around. That's fine, read it anyway and some of it will make a bit of sense and then, as you work with the material, more chunks will start to make sense. Trust me, you will learn a LOT about a LOT more than C. You will get a glimpse of how high level programs are made to work under the hood and that will greatly expand the toolbox you havefor figuring out how to even attack complex problems with an MCU, an FPGA, or even scratch logic.
     
    #14
  15. MrChips

    MrChips Moderator

    Joined:
    Oct 2, 2009
    11,752
    3,010
    This is rudimentary in all computer languages. One needs to be aware of how all variables are stored and manipulated on a computer.
     
    #15
  16. WBahn

    WBahn Moderator

    Joined:
    Mar 31, 2012
    12,677
    3,176
    Agreed. It is one of the reasons why I hate dynamically-typed languages where the compiler/interpretter gets to choose what kind of data storage I need. I don't want a compiler that does too much of my thinking for me and I want to be able to easily force it to do what I want in most circumstances. This is becoming harder and harder to do; yes, it is also making it easier for relatively unskilled programmers to make working code that doesn't have many of the flagrant flaws and weaknesses that a less capable language/compiler might produce, but it also makes programmers stay unskilled and shrinks the pool of programmers that really know what they are doing. As with all things, it's a tradeoff and there really are reasonable and valid arguments for both sides and, as usual, the key is in striking the proper (hard to even define) balance, but for the most part, we aren't even discussing finding a balance, but instead just charging down the road to complete dependency on the tools to take our ill-formed notions and produce quality code that gets it right. There's a day of reckoning down that road.
     
    #16
Loading...