• Forums
• Posts
Latest Posts
Active Posts
Recently Visited
Search Results
• Page Extras
• Forum Themes
• AVR Freaks

### Hot!32 Bit multiplication with PIC

Page: 12 > Showing page 1 of 2
Author
BEsmart
Starting Member
• Total Posts : 37
• Reward points : 0
• Joined: 2019/04/26 06:47:36
• Location: 0
• Status: offline
0

# 32 Bit multiplication with PIC

I know this seems to be a silly question and I also never had problems like this with AVR before...
I'm using an uint_32 variable for a timing intervall counter, but the result of the multiplication seem to be weird, if the number gets too big ... but still way beyond the limit of unsigned 32 bit ( 4294967295 ).

` #include "stdint.h"//...//...   uint32_t intervall;   intervall = 8 * 5000;// -> leads to 40000   => OK!!      intervall = 18 * 5000; // -> leads to 24464   => !!???`

I've been debugging this value with measuring an IO-Pin and also with printing it to UART.
The value of 24464 seem really to be the result of the multplication.

What am I missing???
Many thanks!

bitdoctor
Starting Member
• Total Posts : 26
• Reward points : 0
• Joined: 2019/10/11 06:10:09
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 05:32:38 (permalink)
0
You're missing the code that shows us how you use the result and print it.
Edit - constant expression arithmetic in C is done with int arithmetic, the product is 90,000 which exceeds the size of an int. You need:
`intervall = 18UL * 5000;`

That's also true in AVR land.
post edited by bitdoctor - 2019/10/20 05:46:17
BEsmart
Starting Member
• Total Posts : 37
• Reward points : 0
• Joined: 2019/04/26 06:47:36
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 06:04:14 (permalink)
0
I also tried
`intervall = 18UL * 5000;`

and even
`intervall = 18UL * 5000UL;`

Debugged with IO-Pin and sprintf (outstring , "%s%u" , intervall)...

bitdoctor
Starting Member
• Total Posts : 26
• Reward points : 0
• Joined: 2019/10/11 06:10:09
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 06:14:36 (permalink)
+1 (1)
Why didn't you tell us that? Anyway, the %u specifier is for an unsigned int, not an unsigned long int. Try %ul.
BEsmart
Starting Member
• Total Posts : 37
• Reward points : 0
• Joined: 2019/04/26 06:47:36
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 06:24:03 (permalink)
0
...OK.
Using %ul only leads to 24464l displayed and still not affecting the time intervall on th IO-Port, where the value is meaured as intervall in ms. So it is easy to see, if the value is correct.
bitdoctor
Starting Member
• Total Posts : 26
• Reward points : 0
• Joined: 2019/10/11 06:10:09
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 06:27:43 (permalink)
0
Then post the entire code. Nobody can guess everything you're doing. The number 24464 is the result of the overflow (truncation) of 90,000 which is 90000-2^16, so the general observation that it's an unsigned int overflow is certain.
post edited by bitdoctor - 2019/10/20 06:46:52
BEsmart
Starting Member
• Total Posts : 37
• Reward points : 0
• Joined: 2019/04/26 06:47:36
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 06:46:59 (permalink)
0
Unfortunately the complete code is quite large and this is the only problem I have.
Is it maybe a complier setup problem with XC8?
NorthGuy
Super Member
• Total Posts : 5906
• Reward points : 0
• Joined: 2014/02/23 14:23:23
• Status: online
Re: 32 Bit multiplication with PIC 2019/10/20 06:56:33 (permalink)
+2 (2)
BEsmart
...OK.
Using %ul only leads to 24464l displayed and still not affecting the time intervall on th IO-Port, where the value is meaured as intervall in ms. So it is easy to see, if the value is correct.

It is %lu not %ul.
pcbbc
Super Member
• Total Posts : 1485
• Reward points : 0
• Joined: 2014/03/27 07:04:41
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 06:56:49 (permalink)
+1 (1)
No it’s a truncation to a 16-bit int as previously described.
If the entire project is too big, post a minimum sample project which demonstrates your problem.
BEsmart
Starting Member
• Total Posts : 37
• Reward points : 0
• Joined: 2019/04/26 06:47:36
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 07:09:36 (permalink)
0
OK, I'll do that
1and0
Access is Denied
• Total Posts : 10294
• Reward points : 0
• Joined: 2007/05/06 12:03:20
• Location: Harry's Gray Matter
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 11:40:56 (permalink)
+1 (1)
%ul will print 24464l
%lu will print 90000
Smile:
BEsmart
Starting Member
• Total Posts : 37
• Reward points : 0
• Joined: 2019/04/26 06:47:36
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 13:04:51 (permalink)
0
...yes, that's true! ;-)
But still multiplication is weird:
`uint32_t intervall; intervall = 90000;sprintf (outstring , "%s%lu" , intervall) displays: 90000 -> OK!intervall = 40000 + 50000;sprintf (outstring , "%s%lu" , intervall) displays: 90000 -> OK! intervall = 8 * 5000;sprintf (outstring , "%s%lu" , intervall) displays: 24464 -> weird!!! `

btw. I'm using a PIC18LF46K42 and XC8 2.10
1and0
Access is Denied
• Total Posts : 10294
• Reward points : 0
• Joined: 2007/05/06 12:03:20
• Location: Harry's Gray Matter
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 13:23:23 (permalink)
+1 (1)
BEsmart
But still multiplication is weird:
`uint32_t intervall;   intervall = 8 * 5000;sprintf (outstring , "%s%lu" , intervall) displays: 24464 -> weird!!! `

btw. I'm using a PIC18LF46K42 and XC8 2.10

8 is an int and 5000 is int, so the multiplication is performed using 16-bit with a result of an int which is 16-bit; i.e. the result will be truncated to 16-bit.  So use 32-bit multiplication, that is at least one of the operand must be 32-bit, such as 8UL which is a long.
post edited by 1and0 - 2019/10/20 13:25:26
JPortici
Super Member
• Total Posts : 888
• Reward points : 0
• Joined: 2012/11/17 06:27:45
• Location: Grappaland
• Status: online
Re: 32 Bit multiplication with PIC 2019/10/20 13:24:31 (permalink)
+2 (2)

case 1: hard coded constant doesn't fit in a signed int (16 bit), compiler will use longs (32bit) for calculations
case 2: at least one of hard coded constants in the operation doesn't fit in a signed int, so compiler will use longs for calculations
case 3: both operands fit in a signed int, compiler will use signed ints for the result.
1and0
Access is Denied
• Total Posts : 10294
• Reward points : 0
• Joined: 2007/05/06 12:03:20
• Location: Harry's Gray Matter
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 13:26:17 (permalink)
+1 (1)
Jack_M

case 1: hard coded constant doesn't fit in a signed int (16 bit), compiler will use longs (32bit) for calculations
case 2: at least one of hard coded constants in the operation doesn't fit in a signed int, so compiler will use longs for calculations
case 3: both operands fit in a signed int, compiler will use signed ints for the result.

Yes, yes, yes; and then the result is converted to unsigned long by the = operator.
post edited by 1and0 - 2019/10/20 13:28:40
NorthGuy
Super Member
• Total Posts : 5906
• Reward points : 0
• Joined: 2014/02/23 14:23:23
• Status: online
Re: 32 Bit multiplication with PIC 2019/10/20 13:56:15 (permalink)
0
Jack_M
case 2: at least one of hard coded constants in the operation doesn't fit in a signed int, so compiler will use longs for calculations

Yes, 50000 has "long int" type. All decimal constants are signed. However, since C99, a hexadecimal constant (such as 0xc350, which is seemingly the same) may be unsigned and will be "unsigned int" if it fits into int. So, "40000 + 50000" would produce a result different from "0x9c40 + 0xc350".

jtemples
عُضْوٌ جَدِيد
• Total Posts : 11565
• Reward points : 0
• Joined: 2004/02/13 12:31:19
• Location: Southern California
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 14:21:33 (permalink)
0
All decimal constants are signed.

In C90, an unsuffixed decimal constant can be "unsigned long".

1and0
Access is Denied
• Total Posts : 10294
• Reward points : 0
• Joined: 2007/05/06 12:03:20
• Location: Harry's Gray Matter
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 14:37:14 (permalink)
0
… because C90 does not have long long int. ;)
BEsmart
Starting Member
• Total Posts : 37
• Reward points : 0
• Joined: 2019/04/26 06:47:36
• Location: 0
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 15:08:46 (permalink)
0
...you are rigth! :-)
Everything works fine, if one of the operators is unsigned long.
`intervall = 18 * 5000UL;sprintf (outstring , "%s%lu" , intervall) displays: 90000  -> Now OK!intervall = 18UL * 5000;sprintf (outstring , "%s%lu" , intervall) displays: 90000  -> Now OK!uint32_t number_1;number_1 = 18;intervall =  number_1 * 5000;     sprintf (outstring , "%s%lu" , intervall) displays: 90000  -> Now OK!uint8_t number_1;number_1 = 18;intervall = (uint32_t) number_1 * 5000;     sprintf (outstring , "%s%lu" , intervall) displays: 90000  -> Now OK!`

Many Thanks!!

ric
Super Member
• Total Posts : 25483
• Reward points : 0
• Joined: 2003/11/07 12:41:26
• Location: Australia, Melbourne
• Status: offline
Re: 32 Bit multiplication with PIC 2019/10/20 16:00:08 (permalink)
+1 (1)
This is the usual confusion when people have learnt C on a 32 bit machine, then change to an 8 bit machine without adjusting their assumptions. :)

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
Page: 12 > Showing page 1 of 2