0

update:

Thanks to @Evg from the comments, I realized that the code works as fine when I compiled&runned from another IDE.

Not working IDE(CodeBlocks) compile log:

g++.exe   -c "Y:\ODTÜ DERS VS\EE - 4\441 DATA STRUCTURES\HW-1\hw1_q1.cpp" -o "Y:\ODTÜ DERS VS\EE - 4\441 DATA STRUCTURES\HW-1\hw1_q1.o"
g++.exe  -o "Y:\ODTÜ DERS VS\EE - 4\441 DATA STRUCTURES\HW-1\hw1_q1.exe" "Y:\ODTÜ DERS VS\EE - 4\441 DATA STRUCTURES\HW-1\hw1_q1.o"   
Process terminated with status 0 (0 minute(s), 0 second(s))

Working IDE(Dev-Cpp) compile log:

- Compiler Name: TDM-GCC 4.9.2 64-bit Release

Processing C++ source file...
--------
- C++ Compiler: C:\Program Files (x86)\Dev-Cpp\MinGW64\bin\g++.exe
- Command: g++.exe "Y:\ODTÜ DERS VS\EE - 4\441 DATA STRUCTURES\HW-1\hw1_q1.cpp" -o "Y:\ODTÜ DERS VS\EE - 4\441 DATA STRUCTURES\HW-1\hw1_q1.exe"  -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\include" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\x86_64-w64-mingw32\include" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\4.9.2\include" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\4.9.2\include\c++" -L"C:\Program Files (x86)\Dev-Cpp\MinGW64\lib" -L"C:\Program Files (x86)\Dev-Cpp\MinGW64\x86_64-w64-mingw32\lib" -static-libgcc

Compilation results...

I am trying to get all digits separately of a number, and I am doing this with the below code, though it has some irrelevant parts, I think it is clear.

void IntBoard::writeIntegerToRow(int integer, int row) {

int currentDigit = 0;

if(integer < 0 || integer > (pow(10, DigitCount) - 1)){

    std::cerr << "ERROR: This number either does not fit into our Integer Board or is negative!\n" ;
    return;
}

for (int i=0; i<DigitCount; i++){

    std::cout << "INTEGER FOR THIS CYCLE : " << integer << std::endl;
    currentDigit = integer / pow(10, DigitCount-1-i);
    std::cout << "CURRENT DIGIT FOR THIS CYCLE : " << currentDigit << std::endl;
    setValueOfDigit(currentDigit, row, i);
    integer -= currentDigit * pow(10, DigitCount-1-i);
    std::cout << "The value that will be omitted from INTEGER : " << currentDigit * pow(10, DigitCount-1-i) << std::endl;
    std::cout << "INTEGER FOR NEXT CYCLE : " << integer << "\n" << std::endl;

}

}

DigitCount is 4, defined as global const int. Now, the above code works well for 2 or 3 digit numbers, however, when I try any 4 digit number, the decomposed number is always 1 less than the actual one. I really could not understand why. The output of the above one for the below call is:

ib.writeIntegerToRow(1453, 2);

THE OUTPUT:

INTEGER FOR THIS CYCLE : 1453
CURRENT DIGIT FOR THIS CYCLE : 1
The value that will be omitted from INTEGER : 1000
INTEGER FOR NEXT CYCLE : 452

INTEGER FOR THIS CYCLE : 452
CURRENT DIGIT FOR THIS CYCLE : 4
The value that will be omitted from INTEGER : 400
INTEGER FOR NEXT CYCLE : 52

INTEGER FOR THIS CYCLE : 52
CURRENT DIGIT FOR THIS CYCLE : 5
The value that will be omitted from INTEGER : 50
INTEGER FOR NEXT CYCLE : 2

INTEGER FOR THIS CYCLE : 2
CURRENT DIGIT FOR THIS CYCLE : 2
The value that will be omitted from INTEGER : 2
INTEGER FOR NEXT CYCLE : 0

As you can see, the problem is at the first cycle. I really did not understand why 1453-1000 evaluates to 452. And this happens for all 4 digit numbers. The remaining cycles look working well. What do I miss?


EXAMPLE OF WORKING CASE:

for the function call

ib.writeIntegerToRow(453, 2);

THE OUTPUT:

INTEGER FOR THIS CYCLE : 453
CURRENT DIGIT FOR THIS CYCLE : 0
The value that will be omitted from INTEGER : 0
INTEGER FOR NEXT CYCLE : 453

INTEGER FOR THIS CYCLE : 453
CURRENT DIGIT FOR THIS CYCLE : 4
The value that will be omitted from INTEGER : 400
INTEGER FOR NEXT CYCLE : 53

INTEGER FOR THIS CYCLE : 53
CURRENT DIGIT FOR THIS CYCLE : 5
The value that will be omitted from INTEGER : 50
INTEGER FOR NEXT CYCLE : 3

INTEGER FOR THIS CYCLE : 3
CURRENT DIGIT FOR THIS CYCLE : 3
The value that will be omitted from INTEGER : 3
INTEGER FOR NEXT CYCLE : 0
muyustan
  • 1,555
  • 1
  • 11
  • 23
  • Unrelated. Don't use `std::pow` for integral numbers. That function operates on doubles and for large integers you'll have precision loss. – Evg Oct 18 '20 at 07:29
  • @πάνταῥεῖ no, tried for 1454 and got 1453 – muyustan Oct 18 '20 at 07:30
  • @Evg ok, noted, which function do you recommend then? – muyustan Oct 18 '20 at 07:31
  • @πάνταῥεῖ That division is fp, not integer, because `pow` returns `double`. – Evg Oct 18 '20 at 07:31
  • For example: https://stackoverflow.com/a/101613/1625187 Unfortunately, there is no `pow` for integers in the standard library. – Evg Oct 18 '20 at 07:33
  • 1
    You are looking for modulo: `1234%10 = 4`. – zdf Oct 18 '20 at 07:35
  • @zdf what do you mean? If you mean use modulo operator and go from LSB to MSB, thats another story. I am more of reasoning why the above situation occurs – muyustan Oct 18 '20 at 07:37
  • @muyustan I understand. The reason is integer/fp mixing. Ask yourself how many numbers are between any two numbers and how can you represent them using a finite number of bits. – zdf Oct 18 '20 at 07:41
  • Btw, [can't reproduce](https://godbolt.org/z/Tq4MGT). – Evg Oct 18 '20 at 07:46
  • I am also curious how the same expression could have a different integer result on the two adjacent lines `currentDigit * pow(10, DigitCount-1-i)`. I find it hard to believe the code you are running with that output matches the code pasted here. – Patrick Parker Oct 18 '20 at 07:48
  • It works on my machine. What hardware and compiler are you using? With which flags? – A M Oct 18 '20 at 07:49
  • @ArminMontigny I updated the question related your comment – muyustan Oct 18 '20 at 07:56

1 Answers1

1

Please copy and paste the following minimal reproducable example in your project.


#include <iostream>

const int DigitCount = 4;

int main() {

    int integer = 1453;

    int currentDigit = 0;

    if (integer < 0 || integer >(pow(10, DigitCount) - 1)) {

        std::cerr << "ERROR: This number either does not fit into our Integer Board or is negative!\n";
        return 0;
    }
    for (int i = 0; i < DigitCount; i++) {

        std::cout << "INTEGER FOR THIS CYCLE : " << integer << std::endl;
        currentDigit = integer / pow(10, DigitCount - 1 - i);
        std::cout << "CURRENT DIGIT FOR THIS CYCLE : " << currentDigit << std::endl;
    
        integer -= currentDigit * pow(10, DigitCount - 1 - i);
        std::cout << "The value that will be omitted from INTEGER : " << currentDigit * pow(10, DigitCount - 1 - i) << std::endl;
        std::cout << "INTEGER FOR NEXT CYCLE : " << integer << "\n" << std::endl;

    }
    return 0;
}

The output should be:

enter image description here

If it works, then the problem is elsewhere and you need to provide more code.

If it does not work, then we need to know, on which hardware, with what float or double types (Length in byte) you are working.

Please feed back.

A M
  • 14,694
  • 5
  • 19
  • 44
  • OK, I had to include math.h to your code, anyway, I compiled it directly from the command window(cmd, windows 10, 64 bit) with `g++ test.cpp -o test.exe`. And the result is same with my previous observation, it decomposes it into 1452 instead of 1453, the same output with my original question. However, same code gives the expected(same as your image) output when builded inside Dev-Cpp IDE, with the compile log given in my update to the question. So, I assume using g++ withouth any flags is the reason of this ambigious behaviour I am getting. – muyustan Oct 18 '20 at 11:04
  • @muyustan, could replace first `currentDigit` inside the loop with `auto currentDigit`, the second one with `(int)currentDigit` and show the output? – Evg Oct 18 '20 at 13:17
  • @Evg here you are: https://ibb.co/0ZWfBT4 by the way, I dropped using `pow()` from math.h and implemented my own `pow_int()` function. Now, the issue is resolved after using my own pow_int() function. The only remaining question is what makes it work with devcpp and not work with codeBlocks or manual compiling from terminal without any flags. – muyustan Oct 18 '20 at 13:28
  • @muyustan, my guess is that that compiler implements some non-standard implicit int-double conversions. They presumably can be seen if some debugging outputs are added, which include values before and after conversions. – Evg Oct 18 '20 at 13:32