2

I am trying to initialize an array so that I could use a simple if statement to check if a value was placed into the array or not.

Is this possible?

Here is my code

double number[1024] = {non-numeric value}
int i = 0;
while(1){
    if (number[i] != non-numeric value){

    printf ("%f", number[i]);
    i++;
}
    else
        break;

}
Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
0x41414141
  • 364
  • 3
  • 16

5 Answers5

8

To initialize data to NaN, use the NAN macro defined in <math.h>

#include <math.h>

// initialize to all NaNs
for (int i=0; i<1024; ++i) number[i] = NAN;

To check for NaNs, use the isnan macro from <math.h>

if (!isnan(number[i])) {
    // do something if the value isn’t NaN.
}
Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
2

Use NAN and isnan from <math.h>

    #include <stdio.h>
    #include <math.h>

    // ...

    #define N 1024

    double number[N];
    int i;

    for (i = 0; i < N; i++)
        number[i] = NAN; // Produce NaN

    //...    

    i = 0;
    while (i < N)
    {
        if (!isnan(number[i]))
        {
            printf("%f\n", number[i]);
            i++;
        }
        else
            break;
    }

Live code!

masoud
  • 55,379
  • 16
  • 141
  • 208
1

Try this:

double number[1024];
int i = 0;

for(i=0 ; i<1024 ; ++i)
    number[i] = NAN;

// while true is bad programming practice, use a for instead

for(i=0 ; i<1024 ; ++i) {
    if(number[i]!=number[i]) 
        printf("%ld",number[i]);
    else break;
}
RSFalcon7
  • 2,241
  • 6
  • 34
  • 55
  • i wouldn't go so far as to say `while true` is bad programming practice, but rather that if you have a predefined termination condition, then yes you should have a condition on the loop you use – im so confused Apr 09 '13 at 16:36
  • why is `while(true)` bad practice? Perhaps it is, in *this* instance, but generally speaking? – Nik Bougalis Apr 09 '13 at 16:36
  • you always have a condition to terminate the loop, it may be dependent from the loop computation itself, in this case I use boolean to get out, this allows easy testing and makes the code more readable (this is open to discussion, but generally accepted around my university) – RSFalcon7 Apr 09 '13 at 16:42
  • `NaN` is the macro that defines "Not a Number", check this: http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html – RSFalcon7 Apr 09 '13 at 16:42
  • 1
    The macro is `NAN`, not `NaN`. – Stephen Canon Apr 09 '13 at 16:43
  • my bad, sorry... @NikBougalis for the while true stuff, check this question: http://stackoverflow.com/questions/390481/is-whiletrue-bad-programming-practice – RSFalcon7 Apr 09 '13 at 16:47
  • @RSFalcon7 I see nothing there except people making up excuses as to why their *personal preference* on the matter is best. Again, it's not a good idea in *this* case, but there's nothing inherently bad about `while(true)`. – Nik Bougalis Apr 09 '13 at 16:49
1

Re-purposing NaN to mean "not supplied by the user" is probably a bad idea -- what if the user wants to supply NaN?

Consider using an "optional" data structure to represent each array element.

struct optional_double {
    char has_value;
    double value;
};

struct optional_double number[1024];
int i;

memset(number, 0, sizeof(number));

// Populate the array with data here.

for (i = 0; number[i].has_value; ++i) {
    printf("%f", number[i].value);
}
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • 3
    This is not a repurposing of NaN; this is one of the things it was designed for. – Eric Postpischil Apr 09 '13 at 16:51
  • @EricPostpischil The fact that NaN can mean two things in this context (user didn't supply a value, or the program computed it by e.g. dividing by zero) seems bad to me. There is unnecessary ambiguity that can be resolved by having an explicit flag indicating if the value is present. (NaN might be considered a valid input!) – cdhowie Apr 09 '13 at 16:52
  • 4
    NaN was designed for all of this. First, if you do not want NaNs entered by the user, you can prohibit them. Second, if you do want NaNs entered by the user, you can distinguish them by setting a payload within the NaN. Third, if you want to distinguish NaNs created during computation from other NaNs, you can either set a payload within the NaN or enable traps for exceptions. You can also set NaNs to propagate quietly or to signal. NaNs were designed for this. – Eric Postpischil Apr 09 '13 at 16:55
0

My answer is similar to cdhowie's, but with a key difference. He's right - you shouldn't repurpose NaN to mean "unset". (In fact, setting some arbitrary number like -1234.56789 is safer than that, since it's unlikely anything will equal that, and more likely that a calculation will result in a NaN.) And apparantly, NAN isn't defined in all math.h files, though if it's in yours, that is the easiest way.

I recommend repurposoing NULL for your task.

You effectively want to turn your double into a Nullable type, so why not actually do that?

double* numberPointers[1024];
memset(numberPointers, NULL, 1024 * sizeof(double));
int i = 0;
while(1){
    if (numberPointers[i] != NULL){
        printf ("%f", numberPointers[i]);
        i++;
    }
    else {
        break;
    }
}

The part of this that is difficult is changing your calculation. Instead of something like

void fillArray(double[] number) {
    int i;
    for (i = 0; i < 1024; ++i) {
        number[i] = someCalculation(i);
    }
}

you'd need something like

void fillArray(double*[] numberPointers) {
    int i;
    double result;
    double* d; 
    for (i = 0; i < 1024; ++i) {
        result = someCalculation(i);
        d = (double*)malloc(sizeof(double));
        *d = result;
        numberPointers[i] = d;
    }
} 

And of course, when you're done, you'd need to free all the pointers in numberPointers, but that should be easy:

int i;
for (i = 0; i < 1024; ++i) {
    if (numberPointers(i) != NULL) {
        free(numberPointers(i));
    }
}
Scott Mermelstein
  • 15,174
  • 4
  • 48
  • 76