我的這支程式主要是用來算pi的,用的方式是用Nilakantha series。
在測試這支程式的執行後會印出用Nilakantha series計算的結果和誤差,但發現num到646的時候他的誤差突然變大了,我自己有檢查過但就是找不出問題,想在這邊請教大家
#include <stdio.h>
#include <stdint.h>
int main()
{
uint16_t num;
double Nilakantha_series_pi = 0;
double pi = 3.14159265358979323846;
double abs_pi = 0;
printf("Please enter n (16-bits unsigned): ");
scanf("%hd",&num);
for (uint16_t i = 1 ; i <= num ; i++)
{
if (i == 1)
{
Nilakantha_series_pi = 3;
}
else
{
if (i % 2 == 0)
{
Nilakantha_series_pi += ( 4.0/( ((i-1)*2) * ((i-1)*2+1) * ((i-1)*2+2) ) );
}
else
{
Nilakantha_series_pi -= ( 4.0/( ((i-1)*2) * ((i-1)*2+1) * ((i-1)*2+2) ) );
}
}
printf("n = %d:\n",i);
abs_pi = pi-Nilakantha_series_pi;
if (abs_pi<0)
{
abs_pi*=(-1);
}
printf(" Nilakantha series: %.10lf (%.10lf)\n",Nilakantha_series_pi,abs_pi);
}
}
這是執行後的結果
Hint: integer overflow/整數溢出;
下例小改自你的程式,你看看輸出結果;搭配 "integer overflow"的概念,你應該能看出問題。
(我這是直覺推論,懶得做進一步的驗證;有錯就請多包涵啦~)
#include <stdio.h>
#include <stdint.h>
int main()
{
uint16_t num;
double Nilakantha_series_pi = 0;
double pi = 3.14159265358979323846;
double abs_pi = 0;
//printf("Please enter n (16-bits unsigned): ");
//scanf("%hd",&num);
num = 650;
uint32_t j = 1;
//for (uint16_t i = 1 ; i <= num ; i++)
for (uint16_t i = 1 ; i <= num ; i++, j++)
{
if (i == 1)
{
Nilakantha_series_pi = 3;
}
else
{
if (i % 2 == 0)
{
Nilakantha_series_pi += ( 4.0/( ((i-1)*2) * ((i-1)*2+1) * ((i-1)*2+2) ) );
}
else
{
Nilakantha_series_pi -= ( 4.0/( ((i-1)*2) * ((i-1)*2+1) * ((i-1)*2+2) ) );
}
}
//printf("n = %d:\n",i);
if (i > 640) { // Hint: integer overflow;
printf("n = %hu (%d) / j: %u (%u):\n",
i, ( ((i-1)*2) * ((i-1)*2+1) * ((i-1)*2+2) ),
j, ( ((j-1)*2) * ((j-1)*2+1) * ((j-1)*2+2) )
);
printf(" Element: %e (j: %e)\n",
( 4.0/( ((i-1)*2) * ((i-1)*2+1) * ((i-1)*2+2) ) ),
( 4.0/( ((j-1)*2) * ((j-1)*2+1) * ((j-1)*2+2) ) )
);
}
abs_pi = pi-Nilakantha_series_pi;
if (abs_pi<0)
{
abs_pi*=(-1);
}
//printf(" Nilakantha series: %.10lf (%.10lf)\n",Nilakantha_series_pi,abs_pi);
}
}