Floating Point Exception, but I rounded everything with round(), baffled

This is a discussion on Floating Point Exception, but I rounded everything with round(), baffled within the C Programming forums, part of the General Programming Boards category; I have a problem with the below program which keeps giving me Floating Point Exception during runtime. When I asked ...

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    11

    Question Floating Point Exception, but I rounded everything with round(), baffled

    I have a problem with the below program which keeps giving me Floating Point Exception during runtime.

    When I asked someone for help, at first they told me to make sure I round my ints because I have some divisions with even and odd numbers. So I went through my code and ensured that everything is rounded just in case.

    This is how I compile and these are the results. As you will see my program gets inside of the do_ls() method, and then calls find_col_widths().
    Code:
    Index = 4
    avg = 8
    maxCol is 80, numCol is 10
    testWidths[0]: 5
    testWidths[1]: 7
    testWidths[2]: 7
    testWidths[3]: 16
    got heree
    current testLen 5
    got heree
    current testLen 12
    got heree
    current testLen 19
    got heree
    current testLen 35
    
    Floating point exception
    It is during the execution of find_col_widths() that my program throws Floating Point Exception. Right after the second for loop inside of the while statement. It never gets to this statement : printf("testLen: %d", testLen);

    I am baffled, whyyy???? This program should do what multicolumn ls linux command does, just print a list of files (based on the current size of terminal, with multicolumn output). I know my logic is corrrect, I know how to retrieve filenames and everything should work if I get rid of this exception. Please help I am stuck for hours already. This shouldn't be the case. Has to be something trivial. Help C gurus por favor.

    Code:
    /* ls2.c
    * version
    * problem with division - when  you divide two numbers
    * to compile gcc -lm  lsfixattempt.c -o lsfix
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <dirent.h>
    #include <sys/ioctl.h>
    #include <math.h>
    
    void do_ls(char[]);
    int get_screen_cols();
    int cstring_cmp(const void *a, const void *b);
    void print_files(char *files[], int numFiles, int colWidths[], int numRows);
    void find_col_widths(char *files[], int numFiles);
    
    void pause()
    {
        int c;
        while((c = getchar()) != '\n' && c != EOF);
    }
    
    main(int ac, char *av[])
    {
        if(ac == 1)
        {
            do_ls(".");
        }
        else
        {
            while(--ac)
            {
                printf("%s:\n", *++av);
                do_ls(*av);
            }
        }
    }
    
    int cstring_cmp(const void *a, const void *b)
    {
        const char **ia = (const char **)a;
        const char **ib = (const char **)b;
        return strcmp(*ia, *ib);
    }
    
    void do_ls(char dirname[])
    {
        DIR *dir_ptr;
        struct dirent *direntp;
        int maxEntries = 20;
        int index = 0;
        char *entries[maxEntries];
    
        if( (dir_ptr = opendir(dirname)) == NULL )
        {
            fprintf(stderr, "ls1: cannot open %s\n", dirname);
        }
        else
        {
            while( (direntp = readdir(dir_ptr)) != NULL )
            {
                if( (strcmp(direntp->d_name, ".") != 0) &&
                    (strcmp(direntp->d_name, "..") != 0) )
                {
                    entries[index++] = direntp->d_name;
                }
            }
            closedir(dir_ptr);
            qsort(entries, (size_t)index, sizeof(char *), cstring_cmp);
        
        printf("Index = %d\n", index);
            find_col_widths(entries, index);
        }
    }
    
    void find_col_widths(char *files[], int numFiles)
    {
        int lenArray[numFiles];
        int testWidths[numFiles];
        int avg = 0;
        int i;
    
        for(i=0; i<numFiles; i++)
        {
            testWidths[i] = 0;
            lenArray[i] = strlen(files[i])+2;
      //      printf("lenArray[%d]: %d\n", i, lenArray[i]);
            avg += lenArray[i];
        }
        avg = round(avg/i);
        printf("avg = %d\n", avg);
        //avg /= i;
    
        int maxCol = get_screen_cols();
        int numCol = round(maxCol/avg);
        printf("maxCol is %d, numCol is %d\n", maxCol, numCol);
        int numRows = round(numFiles/numCol)+1;
        int testLen = 0;
        int rowDir = 0;
        int complete = 0;
        int colIndex = 0;
    
        while( !complete )
        {
            for(i=0; i<numFiles; i++)
            {
                if( (i%numRows == 0) && (i != 0) )
                {
                    colIndex++;
                }
                if(testWidths[colIndex] < lenArray[i])
                {
                    testWidths[colIndex] = lenArray[i];
                    printf("testWidths[%d]: %d\n", colIndex, testWidths[colIndex]);
                }
            }
            colIndex = 0;
    
            for(i=0; i<numFiles; i++)
            {   printf("got heree\n");
                testLen += testWidths[i];
            printf("current testLen %d\n", testLen);
            }
        testLen = round(testLen);
            printf("testLen: %d", testLen);
            //pause();
    
            if (testLen > maxCol)
            {
                printf("testLen > maxCol\n");
                if(rowDir > -1)
                {
       //             printf("rowDir > -1\n");
                    numRows++;
                    if(numRows >= numFiles)
                    {
                        complete = 1;
                    }
                    else
                    {
                        rowDir = 1;
                    }
                }
                else
                {
    //                printf("rowDir == -1\n");
                    numRows++;
                 //   complete = 1;
                    rowDir = 1;
                }
            }
            else // testWidth < max num of columns
            {
       //         printf("testLen < maxCol\n");
                if(rowDir < 1)
                {
      //              printf("rowDir > -1\n");
                    numRows--;
                    if(numRows < 0)
                    {
                        numRows = 1;
                        complete = 1;
                    }
                    else
                    {
                        rowDir = 1;
                    }
                }
                else
                {
     //               printf("rowDir == 1\n");
                    complete = 1;
                }
            }
    
            testLen = 0;
            for(i=0; i<numFiles; i++)
            {
                testWidths[i] = 0;
            }
    
      //      printf("rowDir = %d\nnumRows = %d", rowDir, numRows);
     //       pause();
        }
    
        colIndex = 0;
        for(i=0; i<numFiles; i++)
        {
            if( (i%numRows == 0) && (i != 0) )
            {
                colIndex++;
            }
            if(testWidths[colIndex] < lenArray[i])
            {
                testWidths[colIndex] = lenArray[i];
     //           printf("testWidths[%d]: %d\n", colIndex, testWidths[colIndex]);
            }
        }
    
        print_files(files, numFiles, testWidths, numRows);
    }
    
    void print_files(char *files[], int numFiles, int colWidth[], int numRows)
    {
     //   printf("numRows: %d\n", numRows);
    
        int whitespace, i, col, row;
        col = 0;
        row = 0;
    
        while(row < numRows)
        {
            for(i=0; i<numFiles; i++)
            {
                if(i%numRows == row)
                {
                    whitespace = colWidth[col] - strlen(files[i]);
                    printf("%s", files[i]);
                    while(whitespace > 0)
                    {
                        putchar(' ');
                        whitespace--;
                    }
                    col++;
                }
            }
            row++;
            col = 0;
            putchar('\n');
        }
    }
    
    int get_screen_cols()
    {
        struct winsize wbuf;
    
        if( ioctl(0, TIOCGWINSZ, &wbuf) != -1 )
        {
            return wbuf.ws_col;
         //   printf("%d rows x %d cols\n", wbuf.ws_row, wbuf.ws_col);
         //   printf("%d wide x %d tall\n", wbuf.ws_xpixel, wbuf.ws_ypixel);
        }
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,832
    Floating point exceptions are usually the result of dividing by zero. Check all division operations and perhaps print out the denominator before executing those for diagnosis.

  3. #3
    Registered User
    Join Date
    Sep 2011
    Posts
    11
    I have done so. I print out everything just to see how far the program gets.

    It reaches below for loop, prints out proper info, then as soon as it gets out of the loop there is another printf() statement, which is strangely not even reached, Floating Point Exception comes up. Is it possible for it to be problems with maybe my system. I am running ubuntu 11 in virtualbox, I don't understasnd the source of this problem. Like I said, look at it I round everything and print everything. I dont see where after the for loop the things could go wrong. No idea. Any other thoughts? I am really clueless tried everything. Shouldn't spend 3 hours trying to figure out one exception, I was hoping someone here could help. Cmon guys
    Code:
    for(i=0; i<numFiles; i++)        {   printf("got heree\n");
                testLen += testWidths[i];
            printf("current testLen %d\n", testLen);
            }

  4. #4
    Registered User
    Join Date
    Sep 2011
    Posts
    11
    Quote Originally Posted by nonoob View Post
    Floating point exceptions are usually the result of dividing by zero. Check all division operations and perhaps print out the denominator before executing those for diagnosis.
    What else might it be. What do you think happens after the for-loop i mentioned?

  5. #5
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,832
    You need to have a better understanding of float and int. When you do this: avg = round(avg/i); it doesn't make sense. Both 'avg' and 'i' are integers. The division will be integer as well and might truncate to zero. There is no need to round an integer.

    Things like testLen = round(testLen) are likewise odd since testLen is integer to begin with.

    I'm sure somewhere your are dividing by zero.
    Last edited by nonoob; 12-08-2011 at 08:36 AM.

  6. #6
    Registered User
    Join Date
    Sep 2011
    Posts
    11
    Quote Originally Posted by nonoob View Post
    You need to have a better understanding of float and int. When you do this: avg = round(avg/i); it doesn't make sense. Both 'avg' and 'i' are integers. The division will be integer as well and might truncate to zero. There is no need to round an integer.

    Things like testLen = round(testLen) are likewise odd since testLen is integer to begin with.

    I'm sure somewhere your are dividing by zero.
    But would it still work? Because it does produce proper avg value:
    Index = 4
    avg = 8
    maxCol is 80, numCol is 10
    testWidths[0]: 5
    testWidths[1]: 7
    testWidths[2]: 7
    testWidths[3]: 16
    got heree
    current testLen 5
    got heree
    current testLen 12
    got heree
    current testLen 19
    got heree
    current testLen 35

    Floating point exception
    As you can see this line is not where program crashes. But I will get rid of round and do:
    avg = avg/i;



    What else can it be? I explained in the beginning which printf() statement it doesn't reach, which should pinpoint where this exception occurs. Except that after successfully executing that for loop i mention, there is no divisions before printf() statement that follow.

  7. #7
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,832
    Someone else needs to compile your program. I have Microsoft Visual Studio here and it doesn't have ioctl.h. Sorry.

  8. #8
    Registered User
    Join Date
    Sep 2011
    Posts
    11
    problem is nobody else is responding to this thread but you you can compile it with gcc if you have linux box. the point of the program is just to reinvent the multicolumn ls command

  9. #9
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,832
    This is where it divides by zero: if( (i%numRows == 0) && (i != 0) )
    numRows is zero... probably decremented so near the bottom of the loop since it starts out ok.
    Last edited by nonoob; 12-08-2011 at 09:14 AM.

  10. #10
    Registered User
    Join Date
    Sep 2011
    Posts
    11
    Quote Originally Posted by nonoob View Post
    This is where it divides by zero: if( (i%numRows == 0) && (i != 0) )
    numRows is zero... probably decremented so near the bottom of the loop since it starts out ok.
    I think you are right. I am decrementing this value at some point in the for loop, I was setting numRows =1 if it is less than 0 instead of <= 0

    thanks a lot you the man!!!!!! It worked. I feel dumb
    BEFORE if(numRows < 0) AFTER if(numRows <= 0)

    Code:
    if(rowDir < 1)
                {
      //              printf("rowDir > -1\n");
                    numRows--;
                    if(numRows <= 0)
                    {
                        numRows = 1;
                        complete = 1;
                    }
                    else
                    {
                        rowDir = 1;
                    }
                }

  11. #11
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,555
    > * to compile gcc -lm lsfixattempt.c -o lsfix
    Here's an idea

    gcc -lm -g lsfixattempt.c -o lsfix

    Then do
    gdb ./lsfix

    Then at the gdb prompt type "run"

    Then when it crashes, it will be pointing you directly at the line of code causing trouble.
    You then print each divisor to see which is zero.

    Start to learn how to use the tools available.
    "Post on a forum" every time you trip up will only get you so far.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Floating Point Exception
    By Mentallic in forum C Programming
    Replies: 2
    Last Post: 08-12-2011, 06:48 AM
  2. Getting a floating point exception
    By SnertyStan in forum C Programming
    Replies: 13
    Last Post: 03-25-2008, 11:00 AM
  3. floating point exception
    By megastar in forum C Programming
    Replies: 6
    Last Post: 07-09-2007, 04:22 AM
  4. Floating point exception ????
    By wuzzo87 in forum C Programming
    Replies: 3
    Last Post: 04-25-2007, 02:38 AM
  5. floating point exception? what causes these?
    By salvelinus in forum C++ Programming
    Replies: 2
    Last Post: 10-26-2002, 12:12 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21