1

I would like to output like "correct output data" from "input data" by below C program. But the result shows that the values are changed like "actual output data". Let me know how to solve it.

input data
-5190.978 -90026.901 158.677 15 90 81 58
-5165.821 -90011.875 152.742 15 90 89 54
-5158.762 -90010.093 148.083 31 80 82 42

correct output data
-5190.978 -90026.901 158.677 90 81 58
-5165.821 -90011.875 152.742 90 89 54
-5158.762 -90010.093 148.083 80 82 42

actual output data
-5190.978 -90026.898 158.677 90 81 58
-5165.821 -90011.875 152.742 90 89 54
-5158.762 -90010.094 148.083 80 82 42

/***************************************************************************:::
 xyz(ref)rgb2xyzrgb
    19/08/2016
 ver1.1 2009/3/7
 *******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int main(int argc,char *argv[])
{

    FILE *fpr,*fpw;
    int ref,r,g,b;
    float x,y,z;
    float n_x,n_y,n_z;

    /*****************************************************
         2.command line arguments processing
    *******************************************************/
    if(argc!=3)
    {
            fprintf(stderr,"Usage: %s (1)input_org.txt\n(2)write_xyz FILENAME\n",argv[0]);
            exit(1);
    }
    printf("OPEN FILE NAME:%s\n",argv[1]);

        /**********************************************************************************
         **********************************************************************************
         4.  FILE OPEN + Binary File Input
         **********************************************************************************
         *************************************************************************************/

    // open input file
    if((fpr=fopen(argv[1],"rt"))==NULL)
    {
        printf("file cannot be opened。\n");
        exit(1);
    }

    //write file
    if((fpw=fopen(argv[2],"wt"))==NULL)
    {
        fprintf(stderr,"DSM by GSI data.raw\n");
        exit(1);
    }

    while (fscanf(fpr,"%f %f %f %d %d %d %d", &x,&y,&z,&ref,&r,&g,&b) != EOF)
    {
        //printf("%.3f %.3f %.3f %d %d %d\n",x,y,z,r,g,b);
        n_x = roundf(x * 1000) / 1000;
        n_y = roundf(y * 1000) / 1000;
        n_z = roundf(z * 1000) / 1000;
        //printf("%.3f %.3f %.3f %d %d %d\n",n_x,n_y,n_z,r,g,b);        
        fprintf(fpw,"%.3f %.3f %.3f %d %d %d\n",n_x,n_y,n_z,r,g,b);
            //printf("x:%f y:%f z:%f\n", x,y,z);
    }

    fclose(fpr);
    fclose(fpw);

}
LenItsuki
  • 57
  • 1
  • 8
  • 2
    Don't use `float`. **Always** (yes, always) use `double`. Remember to use `round()` instead of `roundf()` and change the conversion specifiers in `scanf()`. – pmg Aug 19 '16 at 11:27
  • 1
    The error was solved by changing float to double. – LenItsuki Aug 19 '16 at 11:50

1 Answers1

2

Instead of -90026.901 computer stores the nearest number that fits the precision. It's 90026.898. Remember that numbers are stored in binary on computers and 901/1000 doesn't have finite binary form. For this reason, some of the precision will be cut.

It would be the same if you tried to print 1/3. It won't print all the digits, but you actually expect it as you're used to decimal system. In binary system, some of the fractions that have finite decimal form won't have one.

The solution? Always try to enlarge macheps which is the arithmetic precision. The easiest would be to use double instead of float. It still doesn't give 100% but it's more probable that will work.

The topic is known as scientific calculation and is pain in a** for programmers.

xenteros
  • 15,586
  • 12
  • 56
  • 91