Author Topic: The Joy of Debugging Computing Phenomena  (Read 319 times)

0 Members and 1 Guest are viewing this topic.

Nation of One

  • { }
  • { ∅, { ∅ } }
  • Posts: 4765
  • Life teaches me not to want it.
    • What Now?
The Joy of Debugging Computing Phenomena
« on: September 25, 2019, 09:58:46 am »
This thread is a spontaneous idea to see if I might document what could be called "the joy of debugging."

When one has given up, when there is little reason to go on living, maybe some nasty logic error, the most difficult to track down, could be the thing that makes one so irritable, he/she is ready to voluntarily slug down the Hemlock, maybe the best thing to do is to take a pill (or a hot bath) and go to sleep instead.

Then, allow the body to rise refreshed, and inspect/explore the code with a fresh mind, injecting std::cout statements near the "problem site" -----

Since even with the debugger, I could not break out of the infinite printing loop, I created a pause function to stick in that area so that when I ran with the debugger, gdb, I could inspect what is going on.

It turns out that size_t is like an unsigned long integer, and I have this size_t j decrementing while j <= 0; but when j decreases by 1 (when current value of j is 0), there is no representation for -1 in data type size_t (from some C-style library <cstddef> ) - hence 0 - 1 = 18446744073709551615.

There it is!    That is the logic error causing the infinite printing.

To pause the program I used this brute force method:

void pause() 
{
    std::cin.clear();
    std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
    std::string dummy;
    std::cout << "\t Press ENTER [ <-----||| ] to continue ... \n";
    std::getline(std::cin, dummy);
}

Then I place this in the area of the code where the "wrong" behavior is spawned:

      for (size_t j = n-1; j >= 0; j--)  {
         y = y*x + P.getMember(j);              // SYNTHETIC DIVISION
         R_local.setMember(j, y);
         std::cout << R_local.getMember(j) << " \t ";
         pause();
         std::cout << "\nj = " << j << '\n';
      }

This is enough to allow me to inspect what is going on in gdb.   This is the great thing about getting your code to compile even when it is not totally "correct."

In gdb I set a break point in the main program that calls the algorithm, then, when I reach that line, step into the function with "s" command.
---------------------------------------------------------------------------------------------------
----------------------------------------------------
716         for (size_t j = n-1; j >= 0; j--)  {
>>> n
717            y = y*x + P.getMember(j);              // SYNTHETIC DIVISION
>>> p j
$12 = 1
>>> n
718            R_local.setMember(j, y);
>>> n
719            std::cout << R_local.getMember(j) << " \t ";
>>> n
720            pause();
>>> n
    | 2 - 1i     15        Press ENTER [ <-----||| ] to continue ...

721            std::cout << "\nj = " << j << '\n';
>>> p j
$13 = 1
>>> n

j = 1
716         for (size_t j = n-1; j >= 0; j--)  {
>>> n
717            y = y*x + P.getMember(j);              // SYNTHETIC DIVISION
>>> n
718            R_local.setMember(j, y);
>>> n
719            std::cout << R_local.getMember(j) << " \t ";
>>> n
720            pause();
>>> n
60 + 29i     Press ENTER [ <-----||| ] to continue ...

721            std::cout << "\nj = " << j << '\n';
>>> p j
$14 = 0
>>> n

j = 0
716         for (size_t j = n-1; j >= 0; j--)  {
>>> p j
$15 = 0
>>> n
717            y = y*x + P.getMember(j);              // SYNTHETIC DIVISION
>>> n
718            R_local.setMember(j, y);
>>> n
719            std::cout << R_local.getMember(j) << " \t ";
>>> n
720            pause();
>>> n
182 + 236i    
   Press ENTER [ <-----||| ] to continue ...

721            std::cout << "\nj = " << j << '\n';
>>> p j
$16 = 18446744073709551615
j = 18446744073709551615
716         for (size_t j = n-1; j >= 0; j--)  {
-----------------------------------------------------------------------------------------

So, rather than change the data type of the decrementing variable j so that it can represent a negative value and stop the loop, I prefer to adjust the values so that it terminates when j = 0.   So, j must start at n instead of n-1, and continue while j > 0.

Then, in the Polynomial getMember and setMember, I will change j to (j-1).

The Devil truly is in the details.

Finding this bug gave me great satisfaction, even if the feeling was only fleeting.  While I certainly must eat something soon, my consciousness is more wrapped up in "math(s)code" or "coding math(s)" than it is with force feeding chicken menstrual cycles into my intestinal tubes.

(I still intend to type up that Artaud letter eventually, as I think he hits a few nails directly on their heads in his PS remarks.)

Something Holden (Raskolnikov with a maths book) would appreciate:

If 0 - 1 gives 18446744073709551615, then this "zero" is actually equivalent (logically in hardware wrap-around phenomena) to the value 18446744073709551616.

One of my silly little command line programs is log(val, base), so I issue:

log(18446744073709551616, 2), which yields 64

The machine is 64-bit.   I don't mean to sound like the Hasidic in PI talking to Max, but I find this stuff kind of fascinating.   

Will my "fix" work?

As Holden Raskolnikov and Alfred Korzybski say, we shall see ...

(never mind the boil near the exit ramp)   :-[   say what?

The gort will invariably make some snide remark at this point, something like:  "That's more than I wanted to know."
« Last Edit: September 25, 2019, 10:58:26 am by Haywire Baboonery »
Things They Will Never Tell YouArthur Schopenhauer has been the most radical and defiant of all troublemakers.

Gorticide @ Nothing that is so, is so DOT edu

~ Tabak und Kaffee Süchtigen ~

Share on Facebook Share on Twitter


Nation of One

  • { }
  • { ∅, { ∅ } }
  • Posts: 4765
  • Life teaches me not to want it.
    • What Now?
Re: The Joy of Debugging Computing Phenomena
« Reply #1 on: September 25, 2019, 11:52:11 am »
That was it.   This is how it works now:
------------------------------------------------------------------------------
(base) mwh@coyote:[~/work/c++/Algebra++/polynomnom/src]:
$ ----> ./polycalc++

--------------------------------------------------------------
Polynomials over which field?

--------------------------------------------------------------
   Q (Polynomial over the field of rational numbers x = a/b)
   R (Polynomial over the field of real numbers x = a.)
   C (Polynomial over the field of complex numbers x = a + i b)

--------------------------------------------------------------
This polynomial is over :  c


--------------------------------------------------------
Choose the operation you would like to perform:

--------------------------------------------------------
   + (addition)
   - (subtraction)
   * (multiplication)
        / (division)
        % (modulus)
        s (synthetic division: quotient, remainder)
   d EXP:::[compute derivative]
   ~ (compare)
        = EXP:::[evaluate]
        M EXP:::[Modular Arithmetic Sub-Menu]
        F EXP:::[change field)
          x (exit)

-----------------------------------------------------------------------
Operation to perform: s



Enter degree of polynomial P(x): 2

Enter coefficient for x^2 :
z = a + i b :

Enter real part as decimal number: a = 2

Enter real b of imaginary part, i b: b = -1

Enter coefficient for x^1 :
z = a + i b :

Enter real part as decimal number: a = 5

Enter real b of imaginary part, i b: b = 0

Enter constant (coefficient for x^0) :
z = a + i b :

Enter real part as decimal number: a = 0

Enter real b of imaginary part, i b: b = -1
Over Complex Field, c = a + bi

Enter c for divisor (x - c):
z = a + i b :

Enter real part as decimal number: a = 4

Enter real b of imaginary part, i b: b = 2

P(x) = (2 - 1i)x^2 + 5x - i


 4 + 2i  |         | f(0)
-----------------------------------------------------
    |  2 - 1i     5     -1i    

    |         | f(4 + 2i)
----------------------------------------------------
    | 2 - 1i     15     60 + 29i    


P(x) = (2 - 1i)x^2 + 5x - i
---------------------------------
D(x) = (x - [4 + 2i])

P(x)/D(x)
_________________________________

Quotient = (2 - 1i)x + 15

Remainder = 60 + 29i

    Press ENTER [ <-----||| ] to continue ...
« Last Edit: September 25, 2019, 12:02:26 pm by Haywire Baboonery »
Things They Will Never Tell YouArthur Schopenhauer has been the most radical and defiant of all troublemakers.

Gorticide @ Nothing that is so, is so DOT edu

~ Tabak und Kaffee Süchtigen ~