簡體   English   中英

-nan返回值/ e(歐拉)提升至功效計算循環

[英]-nan return value / e (euler) raised to a power calculation loop

我正在學習C編程,並制作了以下算法來解決此問題:

鏈接到問題圖片。 該代碼實際上有效,但是最初的循環只有10次重復(rep <= 10),並且p = 3的答案幾乎是正確的,所以我更改了rep <=20。這給了我我的確切答案計算器。 然后我嘗試使用更大的數字12,然后輸出又不准確。 因此,我結束了對rep <= 35的提高。如果我得到了較高重復次數的循環,則會得到“ -nan”,並且如果p的輸入太高,它將是相同的。 因此,僅需查看模式即可知道,當我輸入更高的數字時,不准確的問題將重新出現,但事實並非如此,因為如果我輸入較高的值,則輸出將為NaN。

沒有更高級別的功能是否可以解決? 只想知道我的程序是否適合現在的水平...

#include <stdio.h>

int main()
{
    float p; //the power for e
    float power; //the copy of p for the loop
    float e = 1; //the e number I wanna raise to the power of p
    int x = 1; //the starting number for each factorial generation
    float factorial = 1;
    int rep = 1; //the repeater for the loop

    printf( "Enter the power you want to raise: " );
    scanf( "%f", &p );

    power = p;

    while ( rep <= 35) {
        while ( x > 1) {
            factorial *= x;
            x--;
        }
        e += p / factorial;

        //printf("\nthe value of p: %f", p); (TESTER)
        //printf("\nthe value of factorial: %f", factorial); (TESTER)

        p *= power; //the new value for p
        rep++;
        factorial = 1;
        x = rep; //the new value for the next factorial to be generated

        //printf("\n%f", e); (TESTER)
    }
    printf("%.3f", e);

    return 0;
}

抱歉,如果我遇到語法/拼寫錯誤,我仍在學習該語言。

在開始之前,讓我們將原始代碼作為函數編寫,並進行一些清理:

float exp_original(float x, int rep = 35)
{
   float sum = 1.0f;
   float power = 1.0f;
   for (int i = 1; i <= rep; i++)
   {
      float factorial = 1.0f;
      for (int j = 2; j <= i; j++)
         factorial *= j;
      power *= x;
      sum += power / factorial;
   }
   return sum;
}

您使用了一些不必要的變量,這些變量已被刪除,但除此之外的過程是相同的:從頭開始計算階乘。


讓我們看一下系列中連續項之間的比率:

在此處輸入圖片說明

因此,我們可以簡單地將當前項乘以該表達式以獲得一項:

float exp_iterative(float x, int rep = 35)
{
   float sum = 1.0f;
   float term = 1.0f;
   for (int i = 1; i <= rep; i++)
   {
      term *= x / i;
      sum += term;
   }
   return sum;
}

看起來更簡單,但是更好嗎? 與C庫exp函數(我們假定是最精確的)的比較:

x   exp (C)       exp_orig    exp_iter
-------------------------------------------
1   2.7182817     2.718282    2.718282
2   7.3890562     7.3890567   7.3890567
3   20.085537     20.085539   20.085539
4   54.598148     54.598152   54.598152
5   148.41316     148.41318   148.41316
6   403.4288      403.42871   403.42877
7   1096.6332     1096.6334   1096.6334
8   2980.958      2980.9583   2980.9587
9   8103.084      8103.083    8103.083
10  22026.465     22026.467   22026.465
11  59874.141     59874.148   59874.152
12  162754.8      162754.77   162754.78
13  442413.41     -nan(ind)   442413.38
14  1202604.3     -nan(ind)   1202603.5
15  3269017.3     -nan(ind)   3269007.3
16  8886111       -nan(ind)   8886009
17  24154952      -nan(ind)   24153986
18  65659968      -nan(ind)   65652048
19  1.784823e+08   -nan(ind)  1.7842389e+08
20  4.8516518e+08  -nan(ind)  4.8477536e+08

這兩個自定義實現是精確度的並駕齊驅, 直到 x = 13 ,其中原始結果為NaN 這是因為最高功率項13^35 = 9.7278604e+38超過最大值FLT_MAX = 3.40282e+38 迭代版本中的累計項永遠不會達到極限附近。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM