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
    Messages:
    123
    Location:
    The Great Midwest
    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:
    long result
    
    result=TMR0*139;
    LCDwrite(result)
    works fine until I get to a value over 32767, at which point the LCD displays a negative number. However:

    Code:
    long result
    
    result=TMR0*139;
    result=35306; //(255*139=35306)
    LCDwrite(result)
    Will display just fine. Additionally:

    Code:
    long result
    
    result=TMR0*100;
    result=result+TRM0*39;
    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
  2. MrChips

    MrChips Moderator Staff Member

    Joined:
    Oct 2, 2009
    Messages:
    9,324
    Try converting TMR0 to long first.

    Code:
    long result;
    
    result = TMR0;
    result = result * 139;
    
    Stuntman likes this.
  3. Stuntman

    Stuntman Thread Starter Member

    Joined:
    Mar 28, 2011
    Messages:
    123
    Location:
    The Great Midwest
    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!
  4. WBahn

    WBahn AAC Fanatic!

    Joined:
    Mar 31, 2012
    Messages:
    8,077
    Location:
    Larkspur, Colorado
    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.
  5. chrisw1990

    chrisw1990 Active Member

    Joined:
    Oct 22, 2011
    Messages:
    543
    Location:
    UK, Near Brighton
    you can also use unsigned long.. =] as long as you dont actually need the minus.. but i would assume you dont by the post
  6. CVMichael

    CVMichael Active Member

    Joined:
    Aug 3, 2007
    Messages:
    414
    Location:
    Canada, Toronto
    Or you can use type casting:
    Code:
    long result
    
    result=(long)TMR0 * 139;
    LCDwrite(result)
    
    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.
  7. WBahn

    WBahn AAC Fanatic!

    Joined:
    Mar 31, 2012
    Messages:
    8,077
    Location:
    Larkspur, Colorado
    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.
  8. MrChips

    MrChips Moderator Staff Member

    Joined:
    Oct 2, 2009
    Messages:
    9,324
    This is a good example why I recommend newcomers to microcontrollers to learn ASM first.
  9. WBahn

    WBahn AAC Fanatic!

    Joined:
    Mar 31, 2012
    Messages:
    8,077
    Location:
    Larkspur, Colorado
    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.
  10. MrChips

    MrChips Moderator Staff Member

    Joined:
    Oct 2, 2009
    Messages:
    9,324
    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.
  11. WBahn

    WBahn AAC Fanatic!

    Joined:
    Mar 31, 2012
    Messages:
    8,077
    Location:
    Larkspur, Colorado
    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!
  12. Stuntman

    Stuntman Thread Starter Member

    Joined:
    Mar 28, 2011
    Messages:
    123
    Location:
    The Great Midwest
    I appreciate the comprehensive explanation, I did not realize this was a rudimentary concept in C for mcu's.
  13. CVMichael

    CVMichael Active Member

    Joined:
    Aug 3, 2007
    Messages:
    414
    Location:
    Canada, Toronto
    That's basics in C, in general, not just MCUs
  14. WBahn

    WBahn AAC Fanatic!

    Joined:
    Mar 31, 2012
    Messages:
    8,077
    Location:
    Larkspur, Colorado
    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.
  15. MrChips

    MrChips Moderator Staff Member

    Joined:
    Oct 2, 2009
    Messages:
    9,324
    This is rudimentary in all computer languages. One needs to be aware of how all variables are stored and manipulated on a computer.
  16. WBahn

    WBahn AAC Fanatic!

    Joined:
    Mar 31, 2012
    Messages:
    8,077
    Location:
    Larkspur, Colorado
    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.
Similar Threads: Multiplication issue
Forum Title Date
Embedded Systems and Microcontrollers dsPIC fractional Multiplication Help needed. Aug 24, 2014
Embedded Systems and Microcontrollers How to do multiplication without using math operation ??? Jun 10, 2014
Embedded Systems and Microcontrollers Not performing multiplication and division operation with decimal number in PIC Feb 24, 2014
Embedded Systems and Microcontrollers floating point multiplication/division Jan 13, 2014
Embedded Systems and Microcontrollers PIC Division (multiplication of inverse) Dec 22, 2011

Share This Page