回答編集履歴

2

追記

2022/02/09 13:36

投稿

otn
otn

スコア84663

test CHANGED
@@ -11,4 +11,55 @@
11
11
  .00001000005000016666708333416666805555753968501984
12
12
  ```
13
13
  なので、お書きのプログラムで計算された値は有効桁15桁で正しいようです。
14
+ ### 追記
15
+ `gcc`だとデフォルトでは`long double`は80bit拡張倍精度(19桁)のようなので(16バイトなのに)、オプションで4倍精度(34桁)にします。
16
+ `printf`は4倍精度に対応していないようです。また、浮動小数点関数は倍精度なので使えません。
17
+ ```sh
18
+ gcc -mlong-double-128 -lm -lquadmath -o foo foo.c
19
+ ```
20
+ ```C
21
+ #include <stdio.h>
22
+ #include <math.h>
23
+ #include <quadmath.h>
14
24
 
25
+ typedef long double FLOAT;
26
+ FLOAT kaizyou(int);
27
+
28
+ int main(void){
29
+ int N;
30
+ int n; // 項数
31
+ int k; // 項数カウント
32
+ FLOAT e; // テイラー展開の部分和
33
+ FLOAT er; // exp(x)との差
34
+ FLOAT fx = .00001000005000016666708333416666805555753968Q;
35
+ char buf[100];
36
+
37
+ printf("N = ");
38
+ scanf("%d", &N);
39
+ n = pow(10, N);
40
+ printf("項数 = %d\n", n);
41
+ e = 0.0;
42
+ for(k = n ; k >= 1 ; --k){
43
+ e += kaizyou(k);
44
+ }
45
+ er = e-fx;
46
+ if(er<0) er = -er;
47
+ quadmath_snprintf (buf, sizeof buf, "%.40Qf", e);
48
+ printf("f(x) =\t%s\n", buf);
49
+ quadmath_snprintf (buf, sizeof buf, "%.40Qf", fx);
50
+ printf("解析値=\t%s\n", buf);
51
+ quadmath_snprintf (buf, sizeof buf, "%.40Qf", er);
52
+ printf("誤差=\t%s\n", buf);
53
+ return 0;
54
+ }
55
+
56
+ FLOAT kaizyou(int n){
57
+ int i;
58
+ FLOAT x = 1, d = 0.00001Q;
59
+
60
+ for(i = n ; i >= 1 ; --i){
61
+ x *= d/(FLOAT)i;
62
+ }
63
+ return x;
64
+ }
65
+ ```

1

誤字訂正

2022/02/09 10:51

投稿

otn
otn

スコア84663

test CHANGED
@@ -1,4 +1,4 @@
1
- まず前提として`double`の精度は受信数表現で約15桁というのはご認識されていると思います。
1
+ まず前提として`double`の精度は十進数表現で約15桁というのはご認識されていると思います。
2
2
  `exp(1e-5)`は約15桁の精度を持っていますが、それは先頭の整数部の`1`から15桁です。
3
3
  ということで、
4
4
  > 解析値 =0.0000100000500000696490587870357558131218