1

So, i've made a program which is able to sort arrays, and i'm trying to sort an array containing double FP's, including 2-3 random ones i enter, pos inf, neg inf and a single NaN. so for this purpose i wish to sort the NaN. So my code works, however when trying to sort the NaN, i'm unable to do so. What i'd like to do is sort it to the end, or have it put at the end of the sorted array. Is there anyway I can actually do this? Thanks in advance!!! code is as follows:

int main()
{
int start_s = clock();
int n, k = 4, j; // k is number of elements
double x = -0.0;
double i = 0;
double swap = 0;//used in the function as a place holder and used for swapping between other variables
double a[100] = { (1/x) + (1/i), 2.3, 1/x *0, 1/i };//array of double elements // 1/i * 0 is NaN
//(1 / i) * 0


for (n = 0; n < (k - 1); n++) // for loop consists of variables and statements in order to arrange contents of array
{
  for (j = 0; j < k - n - 1; j++)
    {
      if (a[j] > a[j + 1])

        {
        swap = a[j];
        a[j] = a[j + 1];
        a[j + 1] = swap;

        }
    }
}

cout << "The list of sorted elements within the array, is: " << endl; /* Output message to user */
for (int i = 0; i < k; i++)// Loop up to number of elements within the array
{
    cout << a[i] << " ";/* Output contents of array */
}
cout << endl; //new line

int stop_s = clock();
cout << "The execution time of this sort, is equal to: " << (stop_s - start_s) / double(CLOCKS_PER_SEC) * 1000 << " milliseconds" << endl;



return 0; 
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274

3 Answers3

3

Since you're in C++ land anyway, why not use it to the full. First, indeed, move the NaN's and then sort. I've taken out 'noise' from your code and produced this, it compiles and runs (edit: on gcc-4.4.3). The main difference is that the NaN's are at the beginning but they're easily skipped since you will get a pointer to the start of non-NaN's.

#include <iostream>
#include <algorithm>
#include <math.h>

int main()
{
    int n, k = 4, j; // k is number of elements
    double x = -0.0;
    double i = 0;
    double a[100] = { (1/x) + (1/i), 2.3, 1/x *0, 1/i };//array of double elements // 1/i * 0 is NaN]
    double *ptr; // will point at first non-NaN double

    // divide the list into two parts: NaN's and non-NaN's
    ptr = std::partition(a, a+k, isnan);
    // and sort 'm
    // EDIT: of course, start sorting _after_ the NaNs ...
    std::sort(ptr, a+k);

    cout << "The list of sorted elements within the array, is: " << endl; /* Output message to user */
    for (int i = 0; i < k; i++)// Loop up to number of elements within the array
    {
        cout << a[i] << " ";/* Output contents of array */
    }
    cout << endl; //new line

    return 0;
}
emvee
  • 4,371
  • 23
  • 23
  • Hi, thanks for your help! Using your code, getting compiling errors, that is; Error 1 error C2783: '_FwdIt std::partition(_FwdIt,_FwdIt,_Pr)' : could not deduce template argument for '_Pr' – RazziGstring Feb 19 '15 at 16:49
  • also getting errors with: 2 IntelliSense: no instance of function template "std::partition" matches the argument list argument types are: (double [100], double *, ) and then also: 3 IntelliSense: cannot determine which instance of function template "isnan" is intended ? Any help is much appreciated!!! Thanks :) – RazziGstring Feb 19 '15 at 16:49
  • Bummer, beat me to it. However, your code does not compile. See here why: http://stackoverflow.com/questions/17574242/how-to-use-isnan-as-a-predicate-function-to-stdfind-if-c11. You need to pass `static_cast(isnan)` to `std::partition` or use a lambda. Note that both need C++11. – Bulletmagnet Feb 19 '15 at 16:49
  • Also, you can `sort(ptr, a+k)` to avoid sorting the NaNs. – Bulletmagnet Feb 19 '15 at 16:53
  • Strange. I tested this on gcc-4.4.3 without enabling C++11 support. After I went home I realized that indeed it should have been "sort(ptr, a+k)", but I was in a hurry ... Thanks for correcting that! – emvee Feb 20 '15 at 07:58
2

Do a linear scan, find the NaNs, and move them to the end - by swapping.

Then sort the rest.

You can also fix your comparator, and check for NaN there.

For the actual check see: Checking if a double (or float) is NaN in C++

Community
  • 1
  • 1
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
1

you can use isnan() in cmath to check for NaNs. So, you can just change your comparison line from:

if (a[j] > a[j + 1])

to:

if (!std::isnan(a[j + 1]) && std::isnan(a[j]) || (a[j] > a[j + 1]))

just a reminder, you need to have:

#include <cmath>

at the top of your code.

triple_r
  • 1,037
  • 1
  • 8
  • 21