iT邦幫忙

0

程式執行結果怪怪的,是程式上哪裡有問題嗎?

  • 分享至 

  • xImage

我的這支程式主要是用來算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);
    }
}

https://ithelp.ithome.com.tw/upload/images/20230106/20137686BgFMlr9rfQ.png
這是執行後的結果

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
re.Zero
iT邦研究生 5 級 ‧ 2023-01-06 19:21:42

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);
    }
}

我要發表回答

立即登入回答