wrong result in signed division

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

Not really sure if this is a bug or just C behaviour. This code gives the wrong result for a division, unless I use type casting.

int temp;
uint16_t MOTOR_CURRENT_CAL;
...
// temp is -1250 at this point
// MOTOR_CURRENT_CAL is 485
// This should give -2 for the division

//temp	/= MOTOR_CURRENT_CAL;			// This gives 132
//temp	/= (int) MOTOR_CURRENT_CAL;			// This gives -2

Anyone knows why? Perhaps I should declare MOTOR_CURRENT_CAL as unsigned int instead?

/Jakob Selbing

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

> Anyone knows why?

Because it's C.

You've got a signed and an unsigned value in your first expression
that are equal in the size of their types (the C standard calls that
"conversion rank"), so the integer conversion rules mandate that the
signed operand be converted to unsigned first (*), so your entire
expression will become unsigned. Obviously, the formerly negative
number will become a large positive number that way.

This kind of conversion problems is usually a hint that something in
your logic might be flawed, so double-check the corner cases for each
possible argument value.

(*) That is a bit shortened compared to the standard, but it's the way
things happen in our common two's complement binary integer world.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

dl8dtl wrote:
> Anyone knows why?
This kind of conversion problems is usually a hint that something in
your logic might be flawed, so double-check the corner cases for each
possible argument value.

Well I don't see the logic flaw. That's why I find the behaviour strange. The nominator can be both negative and positive, but the denominator is always positive. And further, C seems to handle conversions more intelligently. E.g. when multiplying one signed and one unsigned variable, the result is correct (I think...?).

/Jakob Selbing

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

Even if the denominator can only be positive, it makes no sense if it
is allowed to become larger than the nominator. But as the only point
in using an unsigned type is to gain the space of the sign bit for
twice as many possible unsigned values, what's the point of using an
unsigned type for the denominator then? Use a signed type, and you're
done. After all, signed types can hold positive values as well, not
only negative ones. ;-)

> E.g. when multiplying one signed and one unsigned variable, the
> result is correct

The same conversions will apply there. But of course, if you're
converting the (implicitly unsigned) result of the right-hand side of
the expression to a signed int on the left-hand side, you won't notice
the operation was actually as an unsigned type initially, as
converting the large unsigned result bit pattern back to a signed
interpretation will yield your negative number you've been interested
in.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.