This question already has answers here:
Why is unsigned integer overflow defined behavior but signed integer overflow isn't?
(6 answers)
Is signed integer overflow still undefined behavior in C++?
(3 answers)
Why is the phrase: "undefined behavior means the compiler can do anything it wants" true?
(2 answers)
Closed 3 months ago.
Firstly, I defined two bit integers, and multiply them. The answer must overflow, and I got a negative number. Then, I defined two 64-bit integers, and multiply them. The answer must overflow, and I expected to get a negative number. But, the result was zero. I don't know why this happen, could anybody give me some help?
The code is below.
#include <iostream>
int main ()
{
int x = 1e9, y = 1e9;
printf("%d\n", x * y);
int64_t a = 36028797018963968;
int64_t b = 36028797018963968;
printf("%ld\n", a * b);
return 0;
}
The result is below.
ubuntu#VM-0-2-ubuntu:~/Projects/Test$ g++ test.cpp -o a
ubuntu#VM-0-2-ubuntu:~/Projects/Test$ ./a
-1486618624
0
Related
This question already has answers here:
Why is this loop being endless?
(3 answers)
Is signed integer overflow still undefined behavior in C++?
(3 answers)
Why does integer overflow work differently inside of if statement conditional?
(2 answers)
Why does integer overflow on x86 with GCC cause an infinite loop?
(6 answers)
Closed 10 months ago.
In my program, I found the loop unable to exit correctly when i is int32_t. It seems like integer overflow, and is much larger than 10, and the loop does not stop.
Please tell me what happened and how I can avoid this error in a large project.
#include <iostream>
#include <stdint.h>
int f(int n){
for (int32_t i = 0; i < 10; ++i)
{
int64_t time = 4500000000 + (i) * 500000000;
std::cout << time<< " i: " << i << std::endl;
}
return 0;
}
int main ()
{
return f(10);
}
code link
If you use GCC 11.2.0 and the -Wall -O2 options, you will see a warning about undefined behavior:
test.cpp: In function 'int f(int)':
test.cpp:7:42: warning: iteration 5 invokes undefined behavior [-Waggressive-loop-optimizations]
7 | int64_t time = 4500000000 + (i) * 500000000;
| ~~~~^~~~~~~~~~~
test.cpp:5:27: note: within this loop
5 | for (int32_t i = 0; i < 10; ++i)
| ~~^~~~
The compiler knows that 5 * 500000000 is too large to fit in an int (which is typically 32-bit). Signed integer overflow is undefined behavior in C++. Therefore, the compiler is free to assume that this overflow never happens, so it will assume that i can never reach 10, so it can get rid of the part of your for loop that checks i < 10. I know that sounds crazy, but if your program does undefined behavior, the compiler is free to do whatever it wants.
Just add some casts to specify that you want to do 64-bit arithmetic. This eliminates the warnings, the overflows, and the undefined behavior:
int64_t time = (int64_t)4500000000 + i * (int64_t)500000000;
Update: For a larger project that could have more bugs, you might consider using GCC's -fwrapv option, which makes the behavior of signed integer overflow be defined. You could also use -fsanitize=signed-integer-overflow or -fsanitize=undefined to detect these issues at run time, if your toolchain supports those options.
This question already has answers here:
Why is my double or int value is always 0 after division?
(5 answers)
Why does division result in zero instead of a decimal?
(5 answers)
Closed 2 years ago.
double res = (double)((a*b)/(a+b));
After trying the above code with inputs 80,70 I am getting the output 37 not 37.333 but after removing one parenthesis i got the right answer.
The right code is:
double res = (double)(a*b)/(a+b);
I am using:
gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)
double res = (double)((a*b)/(a+b));
Casting to double after integer math is applied, where values might have been truncated. Resort to operator precedence.
double res = (double)(a*b)/(a+b);
Here the cast is performed before the divison.
This question already has answers here:
Program behaving strangely on online IDEs
(4 answers)
Closed 3 years ago.
I got this from a facebook post. What's happening here? See the output in ideone. Output is more than 10 lines.
Code:
#include<iostream>
using namespace std;
int main()
{
for (int i = 0; i < 10; ++i)
cout << i*1000000000 << endl;
}
Ideone Link
Your platform most likely has a 32 bit int. So 1'000'000'000 is an int, and the compiler will attempt to evaluate i * 1'000'000'000 as an int too. This results in an overflow from i being 3 onwards.
The behaviour on overflowing a signed integral type is undefined.
Note that this makes the entire program behaviour undefined, which accounts for the multiple lines of output (beyond 10) that you observe.
(If you had chosen 10'000'000'000 say instead then the multiplication would have been evaluated with long long types and the behaviour would be well-defined!)
This question already has answers here:
Why pow(10,5) = 9,999 in C++
(8 answers)
Closed 8 years ago.
#include <iostream.h>
#include <math.h>
int main()
{
int j=2;
int output;
output=pow(10,j);
cout<<output;
return 0;
}
I wrote above code to gcc 12 compiler and got the output 99 instead 100. I don't get the valid reason while searching on various sites. Is there any compiler problem?
Because of integer truncation. pow() returns a floating point value, and due to floating point arithmetic, it is probably ~ 99.999...; however, due to integer truncation, even 99.999... gets truncated down to 99.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Best way to detect integer overflow in C/C++
how do we check if any arithmetic operation like addition, multiplication or subtraction could result in an overflow?
Check the size of the operands first, and use std::numeric_limits. For example, for addition:
#include <limits>
unsigned int a, b; // from somewhere
unsigned int diff = std::numeric_limits<unsigned int>::max() - a;
if (diff < b) { /* error, cannot add a + b */ }
You cannot generally and reliably detect arithmetic errors after the fact, so you have to do all the checking before.
You can easily template this approach to make it work with any numeric type.