1

I am working with an array and am trying to find the first non zero value in the row focus, but when the program runs it says the first value in the row is not zero even when it is. Here is the section of the code that is not working:

leadingIsHere = 0;
goThrough = 0;
while(leadingIsHere == 0)
{
    printf("Before, leadingIsHere: %d, goThrough: %d, array[focus][goThrough]: %lf\n", leadingIsHere, goThrough, array[focus][goThrough]);
    if(array[focus][goThrough] != 0)
    {
        printf("It is happening and array[focus][goThrough]: %lf\n", array[focus][goThrough]);
        leadingIsHere = 1;
        leading = goThrough;
    }//end of if
    printf("After, leadingIsHere: %d, goThrough: %d, array[focus][goThrough]: %lf\n", leadingIsHere, goThrough, array[focus][goThrough]);
    printf("Focus: %d, leading:%d, goThrough: %d array[focus][goThrough]: %lf\n", focus, leading, goThrough, array[focus][goThrough]);
    goThrough++;
}

The printf's are just so I can actually see what all the values I'm working with are, and they show that at all points the value of array[focus][goThrough] is zero, but the part in the if statement still runs. Any help would be very appreciated, thank you.

B0b1
  • 41
  • 6
  • 1
    What is the declaration of `array`? – Barmar Jan 03 '20 at 03:42
  • 6
    you need to show a [mcve] – phuclv Jan 03 '20 at 03:42
  • 1
    add sample input/output for your code – Kamol Hasan Jan 03 '20 at 03:44
  • 4
    From your `printf` format, it would appear that your `array` is of `double` type - and comparing floating-point variables for an *exact* match is often problematical. (Try using `%lg` instead of `%lf` and you may see that the values aren't *quite* zero!) – Adrian Mole Jan 03 '20 at 03:59
  • Since you got a resolution to the first question (this one) via comments and not a formal answer, it might be best to delete this question. If you have a new question, ask it separately — even if you leave this one around to see if @AdrianMole will write an answer. If you get no answer within a day or so, delete it. – Jonathan Leffler Jan 03 '20 at 06:06
  • @AdrianMole — I not infrequently post a comment that proves to be correct. I will then sometimes create an answer and use a notation like `_Transferring comments into an answer._` at the top, then transfer the information from the comment(s) into an answer, usually (almost invariably) with some extra information (but not always a lot). I don't do it every time, but certainly some of the time. (For recent examples, see: https://stackoverflow.com/a/57750624/15168 and https://stackoverflow.com/a/58338596/15168.) – Jonathan Leffler Jan 03 '20 at 06:13
  • @AdrianMole — I don't transfer comments when there's already an answer which says what I want to say (or most of it) and which doesn't contain inaccuracies. However, I have enough reputation that I'm no longer greatly concerned by that; in older times, I might well have made an answer anyway, possibly without noting that I was transferring comments into the answer. I also don't do it if I think the question has limited merit (it is asking for something that should be obvious after reading a C textbook), or if I'm feeling lazy. You don't have to convert perspicacious comments into answers. – Jonathan Leffler Jan 03 '20 at 06:24
  • 1
    As you have accepted my answer, I would now recommend that you rollback the edit you made on this question (as it's no longer relevant, really) and post your new problem as a new question (include a link to this one if it adds context or is relevant). – Adrian Mole Jan 03 '20 at 07:51

1 Answers1

3

Here's a formal answer, expanded from the comments section, following discussions therein...

The format used in your printf calls (using %lf) suggests that your array variable is of double type! But be aware: comparing floating-point variables for an exact match is very often problematical (see here: Is floating point math broken?). Thus, the test if (array[focus][goThrough] != 0) may very well fail if the array element being compared to zero is not quite zero.

Further, your output 'check' will not pick this up, as the %lf format will display the value in fixed-format notation, like 0.000100; this will be OK for values >= 0.0000005 but, if you use this for a value of, say, 1.0e-12, it will 'round' the value to 6 decimal places and display 0.000000 - so you will not spot the error.

However, if you use the %lg format, then the printf function will used fixed-format when that will suffice, but use scientific notation if that's the better way to display the result (reasonably) accurately. If you try this, you will probably see that your array values have very small but not zero values (e.g. 5.4e-200, or some such).

To resolve the issue, you should test to see if your array element (or, to be precise, its magnitude) is greater than a pre-defined, very small value; like this, for example:

const int tolerance = 1.0e-20; // Set to a value small enough to be "considered" zero
if (fabs(array[focus][goThrough]) > tolerance) // Use "fabs" to handle negative numbers
{
    //... Your code
}

Feel free to ask for further clarification and/or explanation.

EDIT: As suggested by Jonathan Leffler, it is generally better to use a 'relative difference' function rather than a fixed value for tolerance (which I have used here for simplicity/brevity).

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • 1
    Nitpick: `>= 0.0000005`. Consider also a 'relative difference' function — such as illustrated in [If statement when x is near a value?](https://stackoverflow.com/a/42682190/15168) – Jonathan Leffler Jan 03 '20 at 06:49