Multiplication issue PIC16F1934

Thread Starter

Stuntman

Joined Mar 28, 2011
222
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:


Rich (BB 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:

Rich (BB code):
long result

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

Rich (BB 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
 

Thread Starter

Stuntman

Joined Mar 28, 2011
222
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!
 

WBahn

Joined Mar 31, 2012
29,976
I assume that the compiler chooses a multiplication algorithm based on the precision of the multiplicands and not the result?
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.
 

CVMichael

Joined Aug 3, 2007
419
Or you can use type casting:
Rich (BB 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.
 

WBahn

Joined Mar 31, 2012
29,976
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.
 

WBahn

Joined Mar 31, 2012
29,976
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.
 

MrChips

Joined Oct 2, 2009
30,707
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.
 

WBahn

Joined Mar 31, 2012
29,976
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!
 

WBahn

Joined Mar 31, 2012
29,976
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.
 

MrChips

Joined Oct 2, 2009
30,707
This is rudimentary in all computer languages. One needs to be aware of how all variables are stored and manipulated on a computer.
 

WBahn

Joined Mar 31, 2012
29,976
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.
 
Top