предложу следующее решение:
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
const unsigned int FQz=24000000;//входная частота таймера.
const float erratum=.00001;//допустимая ошибка.
const unsigned int MAXLOAD=65535;
//unsigned int Fs; //требуемая для установки частота.
void calc(unsigned int Fs, unsigned int *ld1, unsigned int *ld2){
int delta1;
int delta2;
unsigned int ldt1;
unsigned int ldt2;
unsigned int mult=(unsigned int)floor(FQz/(Fs) + 0.5);// получим общее произведение делителя частоты
unsigned int ldx=mult/65535; if(ldx==0){++ldx;}; //возьмём нижнюю оценку для делителя 1.
*ld2=0;
delta2=FQz;// загрузим заведомо превыщающее оценку значение
int cnt=0;
while((ldx<sqrt(mult)))
{
ldt2=(unsigned int)floor( mult/ldx);
ldt1=(unsigned int)floor(mult/ldt2);
if ((ldt2<MAXLOAD)){
delta1=abs(FQz-Fs*ldt1*ldt2);
if(delta1>abs(FQz-Fs*ldt1*(ldt2+1))){
++ldt2;
delta1=abs(FQz-Fs*ldt1*ldt2);
}
if ((delta1<delta2)){//обновим пару делителей, при вновь найденной минимальной ошибке.
*ld1=ldt1;
*ld2=ldt2;
delta2=delta1;
};
if(delta1==0)break;//если найден идеальный результат- остановимся.
//if((float)delta1<erratum*FQz)break;//если найден подходящий результат- остановимся.
if((delta1<erratum*FQz)&&(cnt==0)){cnt=ldx;}//если найден подходящий результат- запомним.
};
++ldx;
};
printf("\nfs=%d; ld1=%u; ld2=%u; delta=%d; ldx=%i; cnt=%i", Fs, *ld1, *ld2, delta2, ldx, cnt );//чисто отладочный вывод
}
int main() {
unsigned int ld1;
unsigned int ld2;
for (int i=1; i<999;i++){
calc(i, &ld1, &ld2);
};
printf("This is SPARTA!\r\n");
}
можно убрать убрать строки, где считается число итераций (cnt), и сразу по достижении приемлемого результата брякаться.