I know that overflow happens when I assign a value larger than INT_MAX
to an int variable, but what happens if this value is divided by a large number too? in the following statement
int x = 3000000000/10000;
will overflow happen?

- 3,929
- 1
- 23
- 30

- 49
- 3
-
1There is no overflow if you assign `INT_MAX` to `int` – Eugene Sh. Jul 14 '20 at 19:15
-
1The maximum value of an `int` (if 32-bits) is `2147483647`. This may be undefined behavior if `3000000000` is converted to an `int`. – Fiddling Bits Jul 14 '20 at 19:17
-
2@FiddlingBits It is rather implementation defined. – Eugene Sh. Jul 14 '20 at 19:20
-
@EugeneSh. exactly as how constant expression 3000000000/10000 will be calculated by the compiler is up to implementation. I do not know is standard says something about it. – 0___________ Jul 14 '20 at 19:26
-
1@P__J__ It is actually well defined. The constants will get types as defined [in this table](http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p5) (so yeah, will depend on the size of the types) and will be followed by [usual arithmetic conversions](http://port70.net/~nsz/c/c11/n1570.html#6.3.1.8) – Eugene Sh. Jul 14 '20 at 19:33
-
@EugeneSh. I do not know. This example contradicts it https://godbolt.org/z/zKqhWM Explicit conversion is needed. – 0___________ Jul 14 '20 at 19:45
-
@P__J__ Not sure why you are saying it is required? Adding the cast as in your example is rather making it implementation defined (you are converting a value that cannot fit the target type into a signed type). Without the cast it is behaving exactly according to the two standard sections I cited. – Eugene Sh. Jul 14 '20 at 20:12
-
@EugeneSh. IMO 30000000000 compiler should convert to int (as it is int constant - no `l` or `ll` suffix), then divide by the 100000. – 0___________ Jul 14 '20 at 20:29
-
2@P__J__ According to the [table](http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p5) if no suffix is provided - it will be converted to `long int` if not fitting into `int`. Or `long long int` if not fitting that too. – Eugene Sh. Jul 14 '20 at 20:32
-
@EugeneSh. plus + – 0___________ Jul 14 '20 at 20:36
4 Answers
If the integer constants (literals) in an expression are representable in types supported by the C compiler, with the correct signedness, the compiler will perform correct arithmetic (as defined by the C standard) on them. If the result can be represented in an int
, then int x = expression;
will initialize x
to have that value.
If the result cannot be represented in an int
, then the result of the initialization is implementation-defined, per C 2018 6.3.1.3 3.
If an integer constant is not representable in any type, with the correct signedness, supported by the C compiler, then the behavior is not defined by the C standard, except that the compiler must provide a diagnostic message (per 6.4.4.1 6 and 6.4.4 3).

- 195,579
- 13
- 168
- 312
You could cast larger numbers as e.g. long long
and then cast the result back to int. That should avoid any overflow.
So like this: https://stackoverflow.com/a/9047811
(Only that you would cast it back to int afterwards by int result = (int)((long long)(numerator)/(long long)(denominator))
.

- 659
- 1
- 9
- 17
I know that overflow happens when I assign a value larger than INT_MAX to an int variable,
Overflow does not occur when the constant is within (unsigned) long long
. Instead this is a conversion of a value out of range of an int
. The result is implementation defined.
When a value with integer type is converted to another integer type other than
_Bool
, if the value can be represented by the new type, it is unchanged.
...
Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised. C17dr 6.3.1.3
A common implementation defined behavior is to lop off upper bits.
int some_int = 0x123456789A; // Out of range
printf("%d\n"); --> possible outcome 0x3456789A as "878082202"
what happens if this value is divided by a large number too? will overflow happen?
No. 3000000000
in this case is a long
or long long
. The quotient is the same type, but of value 300,000. With a 32-bit int
, that converts nicely to a int
with a value of 300,000.
int x = 3000000000/10000;
Appending an LL
in int x = 3000000000LL/10000;
makes not difference in this case.

- 143,097
- 13
- 135
- 256
In your specific case:
int x = 3000000000/10000;
The right side expression is a constant, so the compiler [gcc
, at least], resolves the division at compile time, so the result is 300000
. (To do that, the compiler has to do the constant reduction using higher precision than int
internally)
But, if you do:
int x = 3000000000;
x /= 10000;
You get: -129496
[hence overflow]
That's because x
got an overflow [and became negative] on the first line.
3000000000
still fits in 32 bits (unsigned), so you get the value 0x0xb2d05e00
. Note the MSB [sign bit] is set.
And, when you divide by 10000
, the division will preserve the sign and produce: 0xfffe0628
The two code snippets, at first glance, should produce the same result. But, they don't because the compiler has to honor the two step process (i.e. it can't combine the two steps together).
Otherwise, the compiler would break other code that relies on truncation, etc: (e.g. rounding):
int x = 37;
x /= 10;
x *= 10;
You lucked out because 3000000000
[as I said] fits in unsigned int
. But, if you add an extra 0 (e.g.) 30000000000
, the compiler will flag it:
warning: overflow in conversion from ‘long int’ to ‘int’ changes value from ‘30000000000’ to ‘-64771072’ [-Woverflow]
int x = 30000000000;
^~~~~~~~~~~
So, you really shouldn't rely on a specific result, if you already know you're doing something that is questionable/wrong.
Here's a sample program:
#include <stdio.h>
int
print_x(void)
{
int x = 3000000000/10000;
return x;
}
int
print_y(void)
{
int y = 3000000000;
y /= 10000;
return y;
}
int
print_z(void)
{
int z = 3000000000;
return z;
}
int
print_w(void)
{
int w = 30000000000;
return w;
}
int
main(void)
{
printf("x=%d\n",print_x());
printf("y=%d\n",print_y());
printf("z=%d\n",print_z());
printf("w=%d\n",print_w());
return 0;
}
Here's the program output:
x=300000
y=-129496
z=-1294967296
w=-64771072

- 30,627
- 4
- 24
- 48
-
Since C99, "3000000000 still fits in 32 bits (unsigned)" is true, but the constant is not of type `int` nor `unsigned`. It is at least `long`, if not `long long`. – chux - Reinstate Monica Jul 14 '20 at 20:01
-
@chux-ReinstateMonica Personally, I didn't think it was UB [just that you'd get a truncated result], but some of the top comments suggested otherwise, so, _mea culpa_, I caved a bit. I've removed the UB language from my answer, and added some explanation. – Craig Estey Jul 14 '20 at 20:18