2013-03-31 2 views
0

나는 각 신호가 파장과 강도의 쌍으로 구성되도록 별도의 신호 및 배경 파일에서 파장 및 강도 데이터를 읽는 프로그램을 작성하고 있습니다. 보시다시피 구조체를 만든 다음 루프의 fscanf를 사용하여 구조의 적절한 요소에 값을 할당하면됩니다. 일단 데이터가 읽혀지면, 프로그램은 각 파일의 기록 된 파장이 겹치는 간격, 즉 일반적인 파장 범위에서 데이터를 그려야합니다. 파장은이 겹침이 존재하는 곳에서 완벽하게 정렬되며 일정한 차이가있는 것으로 알려져 있습니다. 따라서, 구조 배열의 어떤 요소를 적용 할 수 있는지를 식별하는 나의 방법은 두 파일의 최소 파장이 더 크고 최대 파장이 더 낮은지를 결정하는 것이 었습니다. 그런 다음 최소 및 최대 최대 값이 낮은 파일의 경우이 값과 더 높은 최소값/더 낮은 값의 차이를 찾은 다음 상수 단계로 나누어 오프셋 할 요소 수를 결정합니다. 이 작업은 수학이 끝날 때를 제외하고 프로그램은 완전히 설명 할 수없는 잘못된 대답을 반환합니다.설명 할 수없는 계산 오류

아래 코드에서 한 요소의 파장과 그 요소 이전의 파장의 차이를 계산하여 lambdastep으로 정의합니다. 필자의 샘플 데이터는 printf에 의해 확인 된 .002이다. 그러나 프로그램을 실행하고 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, ceil 또는 round을 사용해보십시오.

+0

아, 데이터 파일의 숫자가 정확한 것처럼 보였으므로, lambdastep이 .002 이외의 값이 될 가능성을 할인했습니다. round()를 사용했는데 프로그램이 제대로 작동합니다. 도움을 주셔서 감사합니다. –

0

부동 소수점 계산의 내재 된 부정확성과 거의 관련이 있습니다. 많은 유효 자릿수에 lambdastep을 인쇄하려고합니다. 정확한 값이 생각보다 약간 크다는 것을 알게 될 것입니다.

내 샘플 데이터는 printf으로 확인되는 .002입니다.

(lambdastep == .002)을 인쇄 해보십시오.

관련 문제