IIR フィルターとヒストグラムを使用して数学的計算を実行するコードを作成しました。コードは 100% 移植可能で、再入可能で、システム コールを行わず (memset を除く)、倍精度の const と初期化された変数を持ち、math.h、string.h、stdint.h、および stddef.h のみを含みます。組み込みプロセッサで実行するように作られています。
Windows MinGW GCC または Borland C++ を使用してコードをコンパイルおよび実行すると、すべての単体テストに合格します。これは、Linux64 GCC プラットフォームでは発生しません。さらに調査したところ、アルゴリズムが少し不安定になり、出力値が安定した結果に収束せず、代わりに結果がゆっくりと無限大になるため、テストの 1 つが失敗することが示されました。
ほとんどのコードは浮動小数点の倍精度を使用していますが、一部の変数では単精度も使用しています。
この問題に対処する方法について助けが必要です。コードの完全な移植性を保証する必要がありますが、どこを見ればよいかわかりません。また、コードはここに投稿するのに十分な大きさなので、指示があればフォローします。
これは、Linux でのモジュールのコンパイル行です。
gcc -O3 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/flickerModule.d" -MT"src/flickerModule.d" -o "src/flickerModule.o" "../src/flickerModule.c"
これは、Windows でのモジュールのコンパイル行です。
gcc -O0 -g3 -Wall -c -fmessage-length=0 -o src\flickerModule.o ..\src\flickerModule.c
ここに、コードのすべての依存関係を示します。
fanl@fanl-STI:~/WorkFelipe/Codigos/re7k_eclipsewkspace/flicker_unittest/src$ grep -H -n -E 'mem|sqrt|floor' flickerModule.c
flickerModule.c:76: memset(filt, 0x00, sizeof(struct s_filter));
flickerModule.c:81: memset(filt, 0x00, sizeof(struct s_filter));
flickerModule.c:89: memset(&histo->buf, 0x00, sizeof(uint32_t) * NUM_CLASSES);
flickerModule.c:162: return (floorf(x + 0.5));
flickerModule.c:189: memset(&histn, 0x00, sizeof(float) * NUM_CLASSES);
flickerModule.c:262: hp->Urms_meio_ciclo = sqrt(hp->Acc_Urms_meio_ciclo / NUM_AMOSTRAS_MEIO_CICLO_60Hz);
flickerModule.c:370: return (sqrtf(saida));
flickerModule.c:393: p->GanhoNormalizaEntradaFlickerMeter = 1.0 / (p->halfPeriod.Urms_meio_ciclo * sqrt(2));
flickerModule.c:419: dbg->Prms = sqrt(dbg->Acc_Prms / (NUM_AMOSTRAS_1MIN / FATOR_DOWN1));