2013-03-31 48 views
0

我正在寫一個程序,它從單獨的信號和背景文件中讀取波長和強度數據(因此每個文件都由多個波長和強度對組成)。正如你所看到的,我通過創建一個結構來實現這一點,然後在循環中使用fscanf將值分配給結構中的適當元素。一旦數據被讀入,程序應該在每個文件中記錄的波長重疊的時間間隔(即常見的波長範圍)上繪製它。在存在這種重疊的地方,波長完美地對準,並且已知它們以恆定的差異間隔開。因此,我辨別結構陣列中哪些元素適用的方法是確定兩個文件中哪一個的最小波長較高,最大波長較低。然後,對於具有最小和最大最小值的文件,我會找到它與最小/最大值最大值之間的差值,然後用常數步長除以確定有多少元素需要抵消。這是有效的,除了數學完成時,程序返回一個完全不可理解的錯誤答案。令人難以理解的計算錯誤

在下面的代碼中,我通過計算一個元素和它之前元素的波長之間的差異,將常量步定義爲lambdastep。用我的樣本數據,它是.002,這由printf確認。但是,當我運行程序並用lambdastep進行分隔時,我得到的答案不正確。當我運行除以.002的程序時,我得到了正確的答案。爲什麼是這種情況?沒有我能想到的解釋。

#include<stdio.h> 
#include<math.h> 
#include<stdlib.h> 
#include "plots.h" 

struct spectrum{ 
    double lambda; 
    double intensity; 
}; 

main(){ 
double a=0,b=0,c=0,d=0,lambdastep,smin,smax,bmin,bmax,tmin,tmax,sintmin,bintmin,tintmin,sintmax,bintmax,tintmax,ymin,ymax; 
int ns,nb,nt,i=0,sminel,smaxel,bminel,bmaxel,tminel,tmaxel; 
double min(struct spectrum *a,int,int); 
double max(struct spectrum *a,int,int); 
FILE *Input;         
Input = fopen("sig.dat","r"); 
FILE *InputII;        
InputII = fopen("bck.dat","r"); 
fscanf(Input,"%d",&ns); 
fscanf(InputII,"%d",&nb); 
struct spectrum signal[ns]; 
struct spectrum background[nb]; 
struct spectrum *s = &signal[0]; 
struct spectrum *ba = &background[0]; 
s = malloc(ns*sizeof(struct spectrum)); 
ba = malloc(nb*sizeof(struct spectrum)); 
while(fscanf(Input,"%lf%lf",&a,&b) != EOF){ 
    signal[i].lambda = a; 
    signal[i].intensity = b; 
    i++; 
} 
i = 0; 
while(fscanf(InputII,"%lf%lf",&c,&d) != EOF){ 
    background[i].lambda = c; 
    background[i].intensity = d; 
    i++; 
} 
for (i=0; i < ns ;i++){ 
    printf("%.7lf %.7lf\n", signal[i].lambda,signal[i].intensity); 
} 
printf("\n"); 
for (i=0; i < nb ;i++){ 
    printf("%.7lf %.7lf\n", background[i].lambda,background[i].intensity); 
} 
lambdastep = signal[1].lambda - signal[0].lambda;   //this is where I define lambdastep as the interval between two measurements 
smin = signal[0].lambda; 
smax = signal[ns-1].lambda; 
bmin = background[0].lambda; 
bmax = background[nb-1].lambda; 
if (smin > bmin) 
    tmin = smin; 
else 
    tmin = bmin; 
if (smax > bmax) 
    tmax = bmax; 
else 
    tmax = smax; 
printf("%lf %lf %lf %lf %lf %lf %lf\n",lambdastep,smin,smax,bmin,bmax,tmin,tmax); //here is where I confirm that it is .002, which is the expected value 
sminel = (tmin-smin)/(lambdastep); //sminel should be 27, but it returns 26 when lamdastep is used. it works right when .002 is directly entered , but not with lambdastep, even though i already confirmed they are exactly the same. why? 
+0

你可以將它隔離爲簡單的兩個數字的劃分嗎?哪兩個數字? – nneonneo

回答

1

sminel是一個整數,所以(tmin-smin)/lambdastep將被計算爲一個整數,當計算結束。

lambdastep中的一個非常微小的差異可能是獲得例如27.00001和26.99999;當投射到int時,後者截至26。

嘗試使用floor,ceilround以更好地控制返回值的舍入。

+0

啊,由於數據文件中的數字看起來確切,所以我將lambdastep作爲.002的可能性打了折扣。我用round()和程序現在可以正常工作。謝謝你們的幫助。 –

0

它幾乎肯定與浮點計算的內在不精確性有關。嘗試打印出lambdastep以獲得很多有效數字 - 我打賭你會發現它的確切值比你想象的要大一些。

以我的樣本數據,它是.002,這是由printf確認。

嘗試打印出(lambdastep == .002)