kfgz Opublikowano 1 Października 2010 Zgłoś Opublikowano 1 Października 2010 (edytowane) Jest taki sobie prosty program do obliczania dokładności chodu zegarków mechanicznych #include <stdlib.h>#include <string.h>#include <stdio.h>#include <errno.h>#include <math.h>int FileNotFound(char *path) { printf("\n\nError while opening file '%s': %s\n\n", path, strerror(errno)); return 1;}int malloc_fail() { printf("\n\nERROR: Not enougth RAM for allocating buffer\n"); return 1; }int main(int argc, char *argv[]) { FILE *inpf; float atph, t, *arr1, *arr2, *arr3, *tmp, a1_avg = 0, a2_avg = 0, a1_sos = 0, a2_sos = 0, a3_sos = 0; int x, i, arr2_size, arr1_size = 1; inpf = fopen(argv[1], "r"); if(inpf == NULL) { FileNotFound(argv[1]); exit(1); } arr1 = malloc(sizeof(float)); if(arr1 == NULL) { malloc_fail(); exit(1); } while(!feof(inpf)) { if ((x = fscanf(inpf, "%f", &t)) > 0) { arr1[arr1_size - 1] = t; arr1_size++; tmp = realloc(arr1, sizeof(float)*arr1_size); if(arr1 != NULL) { arr1 = tmp; } else { free(arr1); malloc_fail(); exit(1); } } else if(x == 0) break; } fclose(inpf); arr1_size--; arr2_size = arr1_size - 1; if (arr2_size <= 0) { printf("\nNot enough data!\n\n"); exit(1); } arr2 = malloc(sizeof(float)*arr2_size); if(arr2 == NULL) { malloc_fail(); exit(1); } arr3 = malloc(sizeof(float)*arr2_size); if(arr3 == NULL) { malloc_fail(); exit(1); } for(i = 0; i < arr2_size; i++) arr2[i] = arr1[i + 1] - arr1[i]; /*a1_avg*/ for(i = 0; i < arr1_size; i++) a1_avg += arr1[i]; a1_avg /= arr1_size; /*a2_avg*/ for(i = 0; i < arr2_size; i++) a2_avg += arr2[i]; a2_avg /= arr2_size; /*a1_sos*/ for(i = 0; i < arr1_size; i++) a1_sos += (arr1[i] - a1_avg) * (arr1[i] - a1_avg); a1_sos = sqrtf(a1_sos) / arr1_size; /*a2_sos*/ for(i = 0; i < arr2_size; i++) a2_sos += (arr2[i] - a2_avg) * (arr2[i] - a2_avg); a2_sos = sqrtf(a2_sos) / arr2_size; /*tph*/ atph = (3600.0 + a2_avg / 24.0) * 5.0; for(i = 0; i < arr2_size; i++) arr3[i] = (3600.0 + arr2[i] / 24.0) * 5.0; for(i = 0; i < arr2_size; i++) a3_sos += (arr3[i] - atph) * (arr3[i] - atph); a3_sos = sqrtf(a3_sos) / arr2_size; free(arr1); free(arr2); free(arr3); printf("Avg ticks per hour = %.2f +/- %.3f\n", atph, a3_sos); printf("Avg daily drift = %.1f +/- %.2f\n", a2_avg, a2_sos); printf("Avg absoulte drift = %.1f +/- %.2f\n\n", a1_avg, a1_sos); printf("Number of good samples: %d\n\n", arr1_size); return 0;} Wszystko byłoby pięknie gdyby nie to, że po wykonaniu pętli for po linii // ******** // zmienia się wartość ostatniej komórki tablicy arr2 (tj. arr2[arr2_size - 1] = arr3[0]). Gdy usunę komentarz sprzed linii //arr2[arr2_size - 1] = arr1[arr2_size] - arr1[arr2_size - 1]; to arr2 jest już w porządku ale z kolei wtedy arr3[0] = arr2[arr2_size - 1] o_O. Spotkał się ktoś kiedyś z takim "voodoo"? Dane dla programu są w pliku w postaci liczbowej (różnica w czasie w sekundach) np -31-32-27-14-14-6-3-73-3 Wywołanie programu progs plik_z_danymi.txt Edytowane 3 Października 2010 przez kfgz Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Quad Opublikowano 1 Października 2010 Zgłoś Opublikowano 1 Października 2010 Ostatnia linijke w C napisalem pewnie jakies 5 lat temu, ale imho: a)inicjalizujesz wskazniki arr2, arr3 poprzez malloc(jakis_tam_size), a powinno byc jakis_tam_size*size_elementu b)nie jestem pewien ale to wyrazenie w problematycznej linijce // ******** // moze miec typ double a nie float, chociaz wtedy powinien krzyknac cos kompilator. c)ostatnia komorka tablicy arr2 to bedzie arr2[arr2_size -1] a nie arr2[arr2_size] - napisales (tj. arr2[arr2_size] = arr3[0]) a to akurat najprawdopodobniej jest prawda bo kompilator raczej zaalokuje te tablice/wskazniki jeden po drugim - czyli nastepny adres po ostatnim adresie nalezacym do arr2 bedzie pierwsza komorka arr3 :) 1 Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 1 Października 2010 Zgłoś Opublikowano 1 Października 2010 (edytowane) Ad. 1 To może być to. Zaraz sprawdzę. Ad. 2. Nie sądzę. Wszystkie obliczenia są na float. Ad. 3. Literówka ;) Już poprawiłem. EDIT: Jednak to był mój czeski błąd. Dzięki za pierwszą wskazówkę. Kod poprawiłem w poście. W sumie to powinienem się domyśleć po użyciu realloc. No cóż... widocznie miałem dziś małe zaćmienie. Edytowane 1 Października 2010 przez kfgz Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Gość <account_deleted> Opublikowano 1 Października 2010 Zgłoś Opublikowano 1 Października 2010 (edytowane) Może jestem zaspany ale z tego co widzę to: arr1_size = 1; czyli: arr1 = (float*) malloc(1) -> jakoś nie widzę szansy zmieścić float'a w 1 bajcie ;) jeśli już to powinno być: arr1 = (float*) malloc( size_of(float) * arr1_size ); ...itd arr2, arr3 defakto operujesz poza zaalokowanymi obszarami -> mess. edit: jestem zaspany -> Quad już to napisał... Edytowane 1 Października 2010 przez tomazzi Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 1 Października 2010 Zgłoś Opublikowano 1 Października 2010 (edytowane) Też to zauważyłem (tj. arr1 bo 2 i 3 wskazał Quad) i poprawiłem od razu całość. Edytowane 1 Października 2010 przez kfgz Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...