NeemzCr7
NeemzCr7

Reputation: 63

Showing all decimal numbers in C

So I'm trying to print my my data from a file that was already given to me. In our data most of the numbers have 9 decimal places. A starter code was given to me by my teacher and when I try to print the data it only prints up to 6 decimal places. So the last 3 digits don't show up in the output. Also I have tried to write the number of decimal places like %.9f but surprisingly the last three digits are different. For example the number in my data is 1.900195512 while the printed number (set to 9 decimal places) is 1.900195479.

My code is:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
// Declare constants

// Name of file that stores our raw data
#define FILE_NAME "data_1.csv"

// Data size
#define MAX_ROWS 20
#define MAX_COLUMNS 20

// Main entry point for the program
int main(void) {
    // Decalred variables
    int rowIndex = 0;
    int columnIndex = 0;
    float rawData[MAX_ROWS][MAX_COLUMNS]; // 2-dimensional array to store our 
    raw data
    // Misc variables used for reading the data from the file
    float tempfloat = 0.0F;
    float tmp = 0.0F;
    char newline = ' ';

    // ----------------------------------------------------------------------
    // Open the file for reading 
    FILE *infp;
    infp = fopen(FILE_NAME, "r");

    // Check for errors and exit if found
    if (infp == NULL) {
        printf("Error: failed to open %s for reading\n", FILE_NAME);
        return(1);
    }

    // Read the file into the data structure
    for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) {
        // Read up until the last value
        for (columnIndex = 0; columnIndex < MAX_COLUMNS - 1; columnIndex++) {
            if (fscanf_s(infp, "%f,", &tempfloat) != EOF) {
                rawData[rowIndex][columnIndex] = tempfloat;
            } else {
                printf("Error: incorrect file format at row %d, col %d.\n", rowIndex + 1, columnIndex + 1);
                return(1);
            }
        }

        // Read the last value and the newline char
        if (fscanf_s(infp, "%f%c", &tempfloat, &newline) != EOF) {
            // Check if the last character in the line was a \n otherwise an error occured.
            //Xiao: I have added newline != '\n'
            if (newline != '\0' && newline != '\r' && newline != '\n') {
                printf("Error: incorrect file format at line %d. did not find a newline.\n", rowIndex + 1);
                return(1);
            } else {
                rawData[rowIndex][columnIndex] = tempfloat;
            }

            // Reset the character before the next read. 
            newline = ' ';
        }
    }
    // ----------------------------------------------------------------------
    // Print out the rawdata array
    printf(" --- RAW DATA ---\n");
    for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) {
        // Read up until the last value
        for (columnIndex = 0; columnIndex < MAX_COLUMNS; columnIndex++) {
            printf("%.9f ", rawData[rowIndex][columnIndex]);
        }
        printf("\n");
    }

    // Exit
    return (0);
}

Upvotes: 2

Views: 449

Answers (3)

Ishpreet
Ishpreet

Reputation: 5880

float is not accurate after 7 places. Use double instead

#include <stdio.h>

int main() 
{
    float f;
    double d;
    scanf("%f",&f);
    scanf("%lf",&d);
    printf("%.9f\n",f);
    printf("%.9lf\n",d);
    return 0;
}


Input:
0.123456789      // float variable i.e. f
0.123456789      // double variable i.e. d

Output:
0.123456791     //  float precision
0.123456789     //  double precision

Upvotes: 1

chqrlie
chqrlie

Reputation: 144961

The float type does not have enough precision for 9 accurate decimal places. You should use the double type, which you can scan with %lf.

Also do not compare the return value of fscanf() to EOF to detect failure, invalid input may cause 0 to be returned. Just verify the number of successful conversions returned by fscanf().

Here is a modified version:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
// Declare constants

// Name of file that stores our raw data
#define FILE_NAME "data_1.csv"

// Data size
#define MAX_ROWS 20
#define MAX_COLUMNS 20

// Main entry point for the program
int main(void) {
    // Decalred variables
    int rowIndex = 0;
    int columnIndex = 0;
    double rawData[MAX_ROWS][MAX_COLUMNS]; // 2-dimensional array to store our 
    raw data
    // Misc variables used for reading the data from the file
    double tempfloat = 0.0;
    double tmp = 0.0;
    char newline;

    // ----------------------------------------------------------------------
    // Open the file for reading 
    FILE *infp;
    infp = fopen(FILE_NAME, "r");

    // Check for errors and exit if found
    if (infp == NULL) {
        printf("Error: failed to open %s for reading\n", FILE_NAME);
        return(1);
    }

    // Read the file into the data structure
    for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) {
        // Read up until the last value
        for (columnIndex = 0; columnIndex < MAX_COLUMNS - 1; columnIndex++) {
            if (fscanf_s(infp, "%lf,", &tempfloat) == 1) {
                rawData[rowIndex][columnIndex] = tempfloat;
            } else {
                printf("Error: incorrect file format at row %d, col %d.\n", rowIndex + 1, columnIndex + 1);
                return 1;
            }
        }

        // Read the last value and the newline char
        if (fscanf_s(infp, "%lf%c", &tempfloat, &newline) == 2) {
            // Check if the last character in the line was a \n otherwise an error occured.
            //Xiao: I have added newline != '\n'
            if (newline != '\r' && newline != '\n') {
                printf("Error: incorrect file format at line %d. did not find a newline.\n", rowIndex + 1);
                return 1;
            } else {
                rawData[rowIndex][columnIndex] = tempfloat;
            }
        }
    }
    // ----------------------------------------------------------------------
    // Print out the rawdata array
    printf(" --- RAW DATA ---\n");
    for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) {
        // Read up until the last value
        for (columnIndex = 0; columnIndex < MAX_COLUMNS; columnIndex++) {
            printf("%.9f ", rawData[rowIndex][columnIndex]);
        }
        printf("\n");
    }

    // Exit
    return 0;
}

Upvotes: 2

David C. Rankin
David C. Rankin

Reputation: 84569

You can break your problem down into a much more concise example to help isolate the problem. You are attempting to get 9-digit precision out of a type float, that is only good for 6-7. To improve your accuracy, you need to use type double instead.

When you read any user input always, always validate the return of the function used, and any constraints on the value (none in you case).

A short implementation correcting the issue could be:

#include <stdio.h>

int main (void) {

    double d = 0.0;

    printf ("Enter value: ");
    if (scanf ("%lf", &d) == 1)
        printf ("Your value : %.9f\n", d);

    return 0;
}

Example Use/Output

$ ./bin/scanf_double
Enter value: 1.900195512
Your value : 1.900195512

Look over the answers and comments and let me know if you have further questions.

Upvotes: 1

Related Questions