如题,前段时间应对客户需求,在芯片上增加一些功能,发现芯片空间即满,为了能够把新功能加进去,进行了代码的重新优化,发现之前的天文时钟代码占用空间比较大,所以从这个入手,天文时钟的计算方法如下,标准库函数库编译代码13KB左右,经过分析得出,标准的数学库,在处理三角函数的时候耗费空间很大,在经过对其中三角函数改成查表法后,空间骤降到3KB左右,节约了10K空间,为后面新功能的增加创造了条件,提供一个思路给有类似需要的人。注:更改后的算法经测试验证无误,可以在项目上使用。
/*
* Get the days to J2000
* h is UT in decimal hours
* FNday only works between 1901 to 2099 - see Meeus chapter 7
*/
static double FNday(int y, int m, int d, float h)
{
long int luku = -7 * (y + (m + 9) / 12) / 4 + 275 * m / 9 + d;
luku += (long int) y *367;
return (double) luku - 730531.5 + h / 24.0;
}
static double FNrange(double x)
{
double b = 0.5 * x / M_PI;
double a = 2.0 * M_PI * (b - (long) (b));
if (a < 0)
a = 2.0 * M_PI + a;
return a;
}
/* Calculating the hourangle */
static double f0(double lat, double declin)
{
double fo, dfo;
dfo = RADS * (0.5 * SUNDIA + AIRREFR);
if (lat < 0.0)
dfo = -dfo;
fo = get_tan(declin + dfo) * get_tan(lat * RADS);
if (fo > 0.99999)
fo = 1.0;
return get_asin(fo) + M_PI / 2.0;
};
/* Calculating the hourangle for twilight times */
static double f1(double lat, double declin)
{
double fi, df1;
df1 = RADS * 6.0;
if (lat < 0.0)
df1 = -df1;
fi = get_tan(declin + df1) * get_tan(lat * RADS);
if (fi > 0.99999)
fi = 1.0;
return get_asin(fi) + M_PI / 2.0;
}
void sun(sunsetrise *ssr, int year, int month, int day, int tzone, double latit, double longit)
{
double L, g;
double d, lambda;
double obliq, LL, equation, ha, hb;
double settm, riset;
double daylen;
d = FNday(year, month, day, 12);
/* mean longitude of the Sun */
L = FNrange(280.461 * RADS + .9856474 * RADS * d);
/* mean anomaly of the Sun */
g = FNrange(357.528 * RADS + .9856003 * RADS * d);
/* Ecliptic longitude of the Sun */
lambda = FNrange(L + 1.915 * RADS * get_sin(g) + .02 * RADS * get_sin(2 * g));
/* Obliquity of the ecliptic */
obliq = 23.439 * RADS - .0000004 * RADS * d;
/* Find the RA and DEC of the Sun */
/* Find the Equation of Time in minutes */
/* Correction suggested by David Smith */
LL = L - get_atan2(get_cos(obliq) * get_sin(lambda), get_cos(lambda));
if (L < M_PI)
LL += 2.0 * M_PI;
equation = 1440.0 * (1.0 - LL / M_PI / 2.0);
ha = f0(latit, get_asin(get_sin(obliq) * get_sin(lambda)));
hb = f1(latit, get_asin(get_sin(obliq) * get_sin(lambda)));
/* Conversion of angle to hours and minutes */
daylen = DEGS * ha / 7.5;
if (daylen < 0.0001)
daylen = 0.0;
/* arctic winter */
riset = 12.0 - 12.0 * ha / M_PI + (double)tzone - longit / 15.0 + equation / 60.0;
settm = 12.0 + 12.0 * ha / M_PI + (double)tzone - longit / 15.0 + equation / 60.0;
if (riset > 24.0)
riset -= 24.0;
if (settm > 24.0)
settm -= 24.0;
ssr->sunrise_h = (int)riset;
ssr->sunrise_m = (int)((riset - ssr->sunrise_h) * 60);
ssr->sunset_h = (int)settm;
ssr->sunset_m = (int)((settm - ssr->sunset_h) * 60);
ssr->daylen_h = (int)daylen;
ssr->daylen_m = (int)((daylen - ssr->daylen_h) * 60);
}