kfgz Opublikowano 20 Marca 2009 Zgłoś Opublikowano 20 Marca 2009 (edytowane) Witam, Otóż dane do tablicy arr wczytuję z pliku. unsigned char *arr; FILE *inp; int file_size; char t; int pos = 0; inp = fopen(path, "rb"); fseek(inp, 0, SEEK_END); file_size = ftell(inp); fseek(inp, 0, SEEK_SET); arr = new unsigned char [file_size]; while(pos < file_size) { fscanf(inp, "%c", &t); arr[pos] = t; pos++; } fclose(inp); Rozmiar pojedynczej danej to 4 bajty. Te 4 bajty są w tablicy znakowej jak widać powyżej i stanowią zakodowaną zmienną typu float. Funkcja HexToFloat przekształca te 4 bajty na zmienną float typu używalnego do dalszych obliczeń i zapisuje ją w tablicy floatt. Jak widać w funkcji HexToFloat jest trochę mnożenia, dzielenia, dodawania, odejmowania oraz jedna operacja na bitach (&). Marzy mi się coś w miarę prostego konstrukcyjnie i szybkiego. Mam w zasadzie dwa pomysły na optymalizację (czyt. napisanie tej funkcji od zera). Pierwszy pomysł (chyba najbardziej pożądany) to odczyt danych z pliku w taki sposób, żeby od razu dane nadawały się do obliczeń. Drugi pomysł polega na tym, że dane odczytuję do tablicy znakowej (tak jak w kodzie powyżej) ale robię taki trik, że pod adres tablicy floatt wpisuję odpowiednie dane z tablicy arr. W BASICu kiedyś się tak bawiłem za pomocą POKE i PEEK i działało super. Pomożecie? Oczywiście sam też będę próbował coś spłodzić, może zdążę do poniedziałku ;/ Aha, to nie jest żadna praca na studia czy coś w ten deseń. Piszę program z własnej i nie przymuszonej woli i jak go skończę to nie omieszkam opublikować na tym forum i na sourceforge. #include <math.h>#include <stdio.h>#define expbias 127#define bitc 8#define bytec 3void GenPow1(float *tab, int tabsize) { int i; for(i = 0; i < tabsize; i++) tab[i] = pow(2, -127 + i);}void GenPow2(float *tab, int tabsize) { int i; for(i = 0; i < tabsize; i++) tab[i] = pow(2, 7 - i);}void HexToFloat(unsigned char *tab, float *ft, float *pow1, float *pow2, int pos, int tabsize) { unsigned char outtab[32], tt[4]; int i, j, k, idx, tmp1; float sign, frac = 0, exp = 0; for(k = 0; k < tabsize; k++) { tt[0] = tab[0 + pos]; tt[1] = tab[1 + pos]; tt[2] = tab[2 + pos]; tt[3] = tab[3 + pos]; for(i = bytec, idx = 0; i >= 0; i--) for(j = 0; j < bitc; j++) { tmp1 = pow1[127 + j]; outtab[idx] = (tt[i] & tmp1) / tmp1; idx++; } sign = pow(-1, outtab[31]); for(i = 30; i >= 23; i--) exp += outtab[i] * pow2[30 - i]; exp -= expbias; exp = pow(2, exp); for(i = 22; i >= 0; i--) frac += outtab[i] * pow2[30 - i]; frac += 1; ft[k] = sign * exp * frac; exp = 0; frac = 0; pos += 4; }}int main() { float pow1[256], pow2[31], floatt[2]; int i, smpc = 2, offset = 0; unsigned char arr[8] = {0x3E, 0xAA, 0xAA, 0xAB, 0xAB, 0xAA, 0xAA, 0x3E}; GenPow1(pow1, 256); GenPow2(pow2, 31); HexToFloat(arr, floatt, pow1, pow2, offset, smpc); for(i = 0; i < smpc; i++) printf("%e\n", floatt[i]); return(0);} P.S. Przy tworzeniu funkcji HexToFloat korzystałem z http://en.wikipedia.org/wiki/IEEE_754-1985...recision_32-bit oraz http://babbage.cs.qc.edu/IEEE-754/32bit.html EDIT: Temat uważam za zamknięty :D #include <stdio.h>#define floatsize 4void HexToFloat(float *address, unsigned char *byte, int idx) { int i; unsigned char *pByte; for(i = 0; i < floatsize; i++) { pByte = (unsigned char*)address + i; *pByte = byte[3 - i + idx]; } }int main() { float floatt[3] = {1.0, 2.0, 3.0}; int i, smpc = 2, offset = 0; unsigned char arr[8] = {0xAB, 0xAA, 0xAA, 0x3E, 0x3E, 0xAA, 0xAA, 0xAB}; for(i = 0; i < smpc; i++) HexToFloat(&floatt[i], arr, floatsize * i + offset); for(i = 0; i <= 2; i++) printf("%e\n", floatt[i]); return(0);} Drugi algorytmy jest 167 razy szybszy niż pierwszy. To się nazywa optymalizacja ;) Edytowane 20 Marca 2009 przez Dj_AnT Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...