question about multiplication

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I'm using WinAVR and I was wondering why this doesn't work

int16_t a
int16_t b
int16_t c
int32_t d
...
for(....)
...
	d = d + a*b
...
c=d/1000

convert c to string with itoa and send c via RS232

and this works

int16_t a
int16_t b
int16_t c
int32_t d
...
for(....)
...
	d = d + (int32_t)a*(int32_t)b
...
c=d/1000

convert c to string with itoa and send c via RS232.

How do I know when I need to put some attribute before the variable?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
How do I know when I need to put some attribute before the variable?

When a * b might be larger than what fits in a 16 bit int.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You didn't say what specifically does not work, however, it would seem from your examples that you are getting overflow. Because the C promotion rules work by promoting to ( simplifying here ) either an int or the larger type in an expression, the multiplication in your expression is going to result in an int16_t type value which, I believe, is just a typedef of int in avr-libc. The upshot of this is that if you have a value that could be outside the range of an int ( 32767 to -32768 ) the multiplication will overflow and the result will be wrong. By adding the casts to int32_t the overflow would be avoided and the result is always correct. Incidentially, either a or b can be cast to int32_t and it will still work as the other operand will be promoted.

The only way to prevent this failure would be to keep the multiplication of a and b within the range of int16_t or to do the casting, as above. So, after rather a lot of explaination, the answer to your question is that you can figure out if you need to cast based on the expected range of values you will see and the standard promotion rules of the language. Another way to approach the problem, if it is close to fitting and you only need positive values, is to simply switch to unsigned data types and double your maximum value. This has the advantage of reducing the amount of computation required across the board.

Martin Jay McKee

As with most things in engineering, the answer is an unabashed, "It depends."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I need 32-bit data from multiplying two 16-bit data, because a and b have value around (+-)10 000, that is why I use int32_t c, but my question is why, if I have the variable c, which is 32 bit int, why I need to emphasize (int32_t) before a and b

int16_t a
int16_t b
..........
int32_t c = (int32_t)a*(int32_t)b

why c can't directly hold 32-bit value from multiplying two 16-bit value without emphasize (int32_t) before 16-bit integers?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's because the type of (a*b) in c=a*b ; does not depend on the type of c.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I think I get it. This mean that the function for multiplying two 16-bit value will return the result like 16-bit integer, and when emphasize (int32_t) before 16-bit values, 16-bit numbers a and b are converted to 32-bit numbers, then multiplied and returned result like 32-bit value, correct?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

correct?

Yes