I have a pretty basic question, but I am not sure if I understand the concept or not. Suppose we have:
int a = 1000000; int b = 1000000; long long c = a * b;
When I run this, c
shows negative value, so I changed also a
and b
to long long
and then everything was fine. So why do I have to change a
and b
, when their values are in range of int
and their product is assigned to c
(which is long long
)?
I am using C/C++
Multiplication is a matematical operation, it can be used for integers and real numbers.
Program to Multiply Two Numbersprintf("Enter two numbers: "); scanf("%lf %lf", &a, &b); Then, the product of a and b is evaluated and the result is stored in product . product = a * b; Finally, product is displayed on the screen using printf() .
You don't. You cannot multiply strings in c.
Matrix multiplication is another important program that makes use of the two-dimensional arrays to multiply the cluster of values in the form of matrices and with the rules of matrices of mathematics. In this C program, the user will insert the order for a matrix followed by that specific number of elements.
The int
s are not promoted to long long
before multiplication, they remain int
s and the product as well. Then the product is cast to long long
, but too late, overflow has struck.
Having one of a
or b
long long
should work as well, as the other would be promoted.
For arithmetic operators the type of the result is not dependent on what you are assigning the result to but the types of the operands. For arithmetic operators the usual arithmetic conversions are performed on the operands. This is used to bring the operands to a common type, this means for types smaller than unsigned/signed int if the values can fit they are promoted to unsigned/signed int, in this case they are already both int so no conversion is required. See Why must a short be converted to an int before arithmetic operations in C and C++? for the details on why.
What we have now is undefined behavior since signed integer overflow is undefined behavior, this is covered in the draft C++ standard section 5
[Expr] which says:
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. [ Note: most existing implementations of C++ ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and all floating point exceptions vary among machines, and is usually adjustable by a library function. —end note ]
Now-a-days we have sanitizers to catch these types of undefined behavior and using -fsanitize=undefined
with both clang and gcc will catch this at runtime with the following error (see it live):
runtime error: signed integer overflow: 1000000 * 1000000 cannot be represented in type 'int'
For reference section 5.6
[expr.mul] says:
[...]The usual arithmetic conversions are performed on the operands and determine the type of the result.
and section 5
says:
Otherwise, the integral promotions (4.5) shall be performed on both operands.61 Then the following rules shall be applied to the promoted operands
- If both operands have the same type, no further conversion is needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With