2016-08-19 15 views
1

我想通過下面的C程序從「輸入數據」輸出「正確的輸出數據」。但結果表明,這些值如「實際輸出數據」一樣改變。讓我知道如何解決它。由fscanf和fprintf在C程序中的文本文件改變的值

輸入數據
-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

正確的輸出數據
- 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

實際輸出數據
-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); 

} 
+2

請勿使用'浮動'。 **總是**(是的,總是)使用'double'。請記住使用'round()'而不是'roundf()'並更改'scanf()'中的轉換說明符。 – pmg

+1

該錯誤通過將float更改爲double來解決。 – LenItsuki

回答

2

代替-90026.901計算機存儲最近符合精度的數字。這是90026.898。請記住,數字存儲在計算機上的binary中,並且901/1000不具有有限的二進制形式。出於這個原因,一些精度將被削減。

如果您試圖打印1/3,這將是相同的。它不會打印所有的數字,但你實際上期望它,因爲你習慣於十進制系統。在二進制系統中,一些有限小數形式的分數不會有一個。

解決方案?總是嘗試放大macheps這是算術精度。最簡單的方法是使用double而不是float。它仍然沒有給出100%,但更有可能起作用。

該主題被稱爲scientific calculation,對於程序員來說是痛苦的**。

+0

我通過您的解釋瞭解錯誤的原因。 – LenItsuki

+0

@LenItsuki然後點擊回答得分 – xenteros

+1

@xenteros下方的灰色箭頭標記爲有幫助。字面上看,你要求downvote,因爲這是分數下面的箭頭。 ;-)我想你的意思是_tick_。 –