简体   繁体   中英

Wrong addition in C++

double *out;
int size = size1+size2;
string s = "";
int c = 0;
int curr = 0;
for(int i=size-2; i >= 0; i--) {
    cout << "\nP: " << out[i]/size << "\n";
    cout << "Carry: " << c <<"\n";
    curr = out[i]/size + c;
    s += char(curr%10 + '0');
    cout << "Out: " << curr <<"\n";
    c = curr / 10;
}

In this snippet I am trying to add "P" ( out[I]/size ) and "Carry" ( c ) into "Out" ( curr ). As you can see in the output for 41 and 2, the addition comes out to be 42. Can someone explain how?

Output:

P: 20 Carry: 0 Out: 20

P: 41 Carry: 2 Out: 42

P: 37 Carry: 4 Out: 40

P: 43 Carry: 4 Out: 47

P: 49 Carry: 4 Out: 53

P: 83 Carry: 5 Out: 88

Looking past the fact that this is not a well-formed code example due to out being an uninitialized pointer, I'm sure you just chucked it there for illustration instead of actually demonstrating your actual code.

But anyway, if you are doing floating-point division (which is the case with out[i] / size ) then when you output that value with std::cout it will round it to whatever the output precision is. In reality it may be slightly less or slightly more than 41.

Similarly, when you take that value and add c you have the same thing: a floating point value that might be slightly more or slightly less than 43. When you now truncate that to an integer then if it's less than 43 the value will become 42.

Try this:

curr = static_cast<int>(std::round(out[i] / size + c));

In your code, out is not initialized. So your code has undefined behavior (since that variable contains some unknown / unpredictable pointer).

If you compiled with GCC invoked as g++ -Wall -Wextra -g , you should get some warnings.

You could consider coding

int size = size1+size2;
double* out = new double [size];

Then compile your program with all warnings and debug info, and use a debugger (like GDB ) to understand the behavior of your executable.

Take more time to read some good C++ reference , and some good C++ programming book

Be sure to read the documentation of your C++ compiler. For GCC it is here . For Clang it is there .

You could later read some C++ draft standard, like n3337 or buy the latest C++ standard from ISO .

You could find many open source projects coded in C++ (eg FLTK , RefPerSys , Ghudi , Qt , ninja and many others....). Take some time to study their source code (for inspiration)

Regarding floating point operations don't forget to read the Floating Point Guide .

Consider (if so allowed) using the Clang static analyzer on your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM