在XC16编译器的DSP例程头文件(dsp.h)中有以下几行:
/* Some constants. */
#ifndef PI /* [ */
#define PI 3.1415926535897931159979634685441851615905761718750 /* double */
#endif /* ] */
#ifndef SIN_PI_Q /* [ */
#define SIN_PI_Q 0.7071067811865474617150084668537601828575134277343750
/* sin(PI/4), (double) */
#endif /* ] */
但是,PI的值实际上(到相同的小数位数)是:
3.1415926535897932384626433832795028841971693993751
dsp.h定义的值在第16个小数位开始发散。对于双浮点运算,这是临界重要的。对于Q15表示,这并不重要。 sin(pi / 4)的值也偏离小数点后16位的正确值。
为什么Microchip使用的值不正确?是否有一些与计算trig函数值有关的深奥理由,或者这只是一个错误?或者也许没关系?
答案 0 :(得分:2)
事实证明两者都是:
3.1415926535897931159979634685441851615905761718750
和
3.1415926535897932384626433832795028841971693993751
转换为double(64位浮点数)时,由相同的二进制数表示:
3.14159265358979311599796346854
(0x400921FB54442D18)
因此在这种情况下没有任何区别。
至于为什么他们使用不同的号码?并非所有生成PI的算法都会逐位生成。有些产生了一系列仅仅收敛于pi而不是一次产生一个数字的数字。一个很好的例子是PI的小数值。 22 / 7,179 / 57,245 / 78,355 / 113等等都越来越接近PI,但他们并没有逐个数字地做到这一点。类似地,多边形近似方法很受欢迎,因为它们可以通过计算机程序轻松计算,可以计算越来越接近PI的连续数字,但不是逐位数字。
答案 1 :(得分:0)
有时会对这些值进行调整以强制舍入到机器编号。 17(包括逗号之前)重要的地方是双重不精确的地方(并且编译器中用于计算精度有限的值的操作甚至可能使其恶化)
所以库程序员可能已经操纵了这个值,以确保从源中的十进制表示到“真正”四舍五入到最接近的二进制数。
测试将以二进制形式写出数字,并且可能在前52位数之后,剩余数字将为零。
IOW这是16-19位十进制pi数的最佳二进制表示形式,转换为十进制数,可以产生额外的数字。