3
#include <iostream>
#include <cmath>

using namespace std;

int main()
{
 double a = sqrt(2);
 cout << a << endl;
}

hi this is the program to find sqrt of 2 it prints just 1.41421 in the output how to implement it in way such that it will print 200000 digits after decimal point

1.41421..........upto 200 000 digits

Is there any approach to print like this?

4

4 に答える 4

6

ことが示せる.

sqrt(2) = (239/169)*1/sqrt(1-1/57122)

また、1/sqrt(1-1/57122) は、テイラー級数展開を使用して効率的に計算できます。

1/sqrt(1-x) = 1 + (1/2)x + (1.3)/(2.4)x^2 + (1.3.5)/(2.4.6)x^3 + ...

この方法を使用する C プログラムも利用できます(少し再フォーマットして修正しました)。

/*
** Pascal Sebah : July 1999
**
** Subject:
**
**    A very easy program to compute sqrt(2) with many digits.
**    No optimisations, no tricks, just a basic program to learn how
**    to compute in multiprecision.
**
** Formula:
**
**    sqrt(2) = (239/169)*1/sqrt(1-1/57122)
**
** Data:
**
**    A big real (or multiprecision real) is defined in base B as:
**      X = x(0) + x(1)/B^1 + ... + x(n-1)/B^(n-1)
**      where 0<=x(i)<B
**
** Results: (PentiumII, 450Mhz)
**
**    1000   decimals :   0.02seconds
**    10000  decimals :   1.7s
**    100000 decimals : 176.0s
**
** With a little work it's possible to reduce those computation
** times by a factor of 3 and more.
*/

#include <stdio.h>
#include <stdlib.h>

long B = 10000; /* Working base */
long LB = 4;    /* Log10(base)  */

/*
** Set the big real x to the small integer Integer
*/
void SetToInteger(long n, long* x, long Integer)
{
  long i;
  for (i = 1; i < n; i++)
    x[i] = 0;
  x[0] = Integer;
}

/*
** Is the big real x equal to zero ?
*/
long IsZero(long n, long* x)
{
  long i;
  for (i = 0; i < n; i++)
    if (x[i])
      return 0;
  return 1;
}

/*
** Addition of big reals : x += y
**  Like school addition with carry management
*/
void Add(long n, long* x, long* y)
{
  long carry = 0, i;
  for (i = n - 1; i >= 0; i--)
  {
    x[i] += y[i] + carry;
    if (x[i] < B)
      carry = 0;
    else
    {
      carry = 1;
      x[i] -= B;
    }
  }
}

/*
** Multiplication of the big real x by the integer q
*/
void Mul(long n, long* x, long q)
{
  long carry = 0, xi, i;
  for (i = n - 1; i >= 0; i--)
  {
    xi = x[i] * q;
    xi += carry;
    if (xi >= B)
    {
      carry = xi / B;
      xi -= carry * B;
    }
    else
      carry = 0;
    x[i] = xi;
  }
}

/*
** Division of the big real x by the integer d
**  Like school division with carry management
*/
void Div(long n, long* x, long d)
{
  long carry = 0, xi, q, i;
  for (i = 0; i < n; i++)
  {
    xi    = x[i] + carry * B;
    q     = xi / d;
    carry = xi - q * d;
    x[i]  = q;
  }  
}

/*
** Print the big real x
*/
void Print(long n, long* x)
{
  long i;
  printf("%ld.", x[0]);
  for (i = 1; i < n; i++)
    printf("%04ld", x[i]);
  printf("\n");
}

/*
** Computation of the constant sqrt(2)
*/
int main(void)
{
  long NbDigits = 200000, size = 1 + NbDigits / LB;
  long* r2 = malloc(size * sizeof(long));
  long* uk = malloc(size * sizeof(long));
  long k = 1;
  /*
  ** Formula used:
  **    sqrt(2) = (239/169)*1/sqrt(1-1/57122)
  ** and
  **   1/sqrt(1-x) = 1+(1/2)x+(1.3)/(2.4)x^2+(1.3.5)/(2.4.6)x^3+...
  */
  SetToInteger(size, r2, 1); /* r2 = 1 */
  SetToInteger(size, uk, 1); /* uk = 1 */
  while (!IsZero(size, uk))
  {
    Div(size, uk, 57122); /* uk = u(k-1)/57122 * (2k-1)/(2k) */
    Div(size, uk, 2 * k);
    Mul(size, uk, 2 * k - 1);
    Add(size, r2, uk);    /* r2 = r2+uk */
    k++;
  }
  Mul(size, r2, 239);
  Div(size, r2, 169);  /* r2 = (239/169)*r2 */

  Print(size, r2);     /* Print out of sqrt(2) */

  free(r2);
  free(uk);

  return 0;
}

200,000 桁の sqrt(2) を計算するには、約 1 分かかります。

ただし、200,000 桁では、累積された丸め誤差のために生成された最後の 11 桁が正しくないことに注意してください。200,000 桁の正しい桁が必要な場合は、200,012 桁に対して実行する必要があります。

于 2013-03-15T13:57:34.237 に答える
5

これは、GNU GMP ライブラリを使用する質問のコードです。コードは 1000 桁の sqrt(2) を出力し、要求を満たすためにコメント行の数字を増やします。

#include <stdio.h>
#include <gmp.h>

int main(int argc, char *argv[])
{
  mpf_t res,two;
  mpf_set_default_prec(1000000); // Increase this number.
  mpf_init(res);
  mpf_init(two);
  mpf_set_str(two, "2", 10);
  mpf_sqrt (res, two); 
  gmp_printf("%.1000Ff\n\n", res); // increase this number.
  return 0;
}

次のコマンドでコンパイルしてください。

$gcc gmp.c  -lgmp -lm -O0 -g3
于 2013-03-12T13:52:51.053 に答える
2

これは、古き良き Prolog プログラミング言語で 1 分未満で 100 万桁の sqrt(2) を計算するソリューションです。これは、ペル方程式を解くことに基づいています。こちらも参照してください。

p*p+1 = 2*q*q

再帰関係 p'=3p+4q および q'=2p+3q は、行列の乗算としてキャストできます。つまり、ベクトル [p,q] に係数の行列を掛けると、ベクトル [p',q'] が得られることがわかります。

| p' |    | 3  4 |   | p |
|    | =  |      | * |   |
| q' |    | 2  3 |   | q |

行列 A の場合、O(log n) 演算で A^n を計算できるように、バイナリ再帰を使用できます。大きな数字が必要になります。ここでは、この実験的なコードを使用しています。これにより、メイン プログラムは次のようになります。

/**
  * pell(N, R):
  * Compute the N-the solution to p*p+1=2*q*q via matrices and return
  * p/q in decimal format in R.
  */
pell(N, R) :-
   X is [[3,4],[2,3]],
   Y is X^N,
   Z is Y*[[1],[1]],
   R is Z[1,1]*10^N//Z[2,1].

次のスクリーンショットは、タイミングといくつかの結果を示しています。私は100万回の反復を10回使用していました。このページの結果と比較できます

ここに画像の説明を入力

欠けているのは、何桁が安定しているかを示す明確な基準と計算です。そのためにはもう少し時間が必要です。

編集 20.12.2016:
相対誤差の上限によってコードを少し改善し、さらに結果を微調整して安定した数字を計算しました。100 万桁の計算時間は 2 秒未満になりました。

?- time(pell(653124, _, S)).
% Uptime 1,646 ms, GC Time 30 ms, Thread Cpu Time 1,640 ms
S = -1000000
于 2016-12-05T19:44:12.930 に答える
1

提供する例は、倍精度演算の精度に関する限り正確です。これは、ほとんどのC++コンパイラが使用する最高の精度です。一般に、コンピューターはより高精度の計算を行うためのツールではありません。これが何らかの宿題である場合は、計算のアルゴリズムを理解する必要があると思います。必要なすべての精度を維持するには、何らかの方法で独自の数字の配列を維持する必要があります。実際のアプリケーションがある場合は、この種の演算を行うために特別に作成された高精度のライブラリを使用する必要があります(GMPはオープンソースの可能性が高いです)。これは複雑なホイールであり、再発明する必要はありません。

于 2013-03-12T13:12:18.830 に答える