4

I want to multiply two numbers , and I know that my numbers are always positive , then :

unsigned int mulPositiveNumbers(unsigned int a ,unsigned int b)
{
    assert(a > 0);
    assert(b > 0);
    return (a*b);
}

Now ,I'm using assert to tell myself that "the given numbers are always positive" .

But when I run :

int main()
{

    unsigned int res = mulPositiveNumbers(-4,3);

        // more stuff goes here

}

The code doesn't fail , even though that I'm using a negative number . Why ?

JAN
  • 21,236
  • 66
  • 181
  • 318

5 Answers5

7

Because a and b are unsigned, they can never be negative. The only way your assertions can fail is if one of them is 0.

When you call your function with a signed int as a parameter, it will simply be converted to an unsigned it before the function executes (and thus before your asserts are checked). Converting a negative integer to an unsigned it will produce a positive integer because, as I said, there are no negative unsigned integers.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • 1
    Okay , then what you mean is that `assert()` in this case is not necessary ? – JAN Aug 29 '12 at 10:01
  • @ron They're necessary to make sure that `a` and `b` are not 0 (assuming `a` and `b` must not be 0 - if they're allowed to be 0, your asserts would actually be wrong). If that's not an issue, they don't serve a purpose. You might want to add asserts everywhere where you *call* your function with signed ints as arguments to make sure that no negative ints are converted to unsigned ints (because if that happens presumably something went wrong somewhere and the conversion would hide an error). – sepp2k Aug 29 '12 at 10:06
3

You're not using a negative, it's converted to an unsigned int because that's what the function takes as parameter.

The assertions can only fail if the numbers are 0.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
3

Your type 'unsigned int' converts implicitly -4 to unsigned equivalent

marcinj
  • 48,511
  • 9
  • 79
  • 100
1

Because -4 interpreted as an unsigned (32 bit) int is 4294967291, which is definitely positive.

The following should work as you intend it to.

unsigned int mulPositiveNumbers(int a, int b)
{
    assert(a > 0); // Fail for (-4, 3)
    assert(b > 0);
    return (a*b);
}

While you are at it, you should also assert for whether the result of the multiplication will overflow, or choose a larger return type (e.g. long long)

Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • 1
    Note that changing `unsigned int` to `int` will cut down the range of possible values by half. – sepp2k Aug 29 '12 at 10:12
  • 1
    `long` isn't necessarily larger than `int` -- it's ranked higher but still might be the same size. And it often is the same size, for example on 32 bit linux and on all Windows. – Steve Jessop Aug 29 '12 at 11:03
  • @SteveJessop good point - I've done too much C# recently. Updated. – StuartLC Aug 29 '12 at 11:08
0

Try this:

(unsigned int a ,unsigned int b)
Rostyslav Dzinko
  • 39,424
  • 5
  • 49
  • 62
Martin James
  • 24,453
  • 3
  • 36
  • 60