teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

debug用の puts(buf); を削除

2020/05/26 14:21

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -60,7 +60,6 @@
60
60
  {
61
61
  char buf[28];
62
62
  sprintf(buf, "%+.13a", x);
63
- puts(buf);
64
63
  return atoi(buf + 19);
65
64
  }
66
65
 
@@ -80,4 +79,7 @@
80
79
  printf("%d\n", get_exp3(d));
81
80
  }
82
81
  }
83
- ```
82
+ ```
83
+
84
+ **追記3**
85
+ get_exp2 にデバッグ用の puts(buf); が残っていたのを削除しました。

2

double のコードを追加

2020/05/26 14:21

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -42,4 +42,42 @@
42
42
  frexpf(x, &exp);
43
43
  return exp - 1;
44
44
  }
45
+ ```
46
+
47
+ **追記2**
48
+ double の場合です。
49
+ ```C
50
+ #include <stdio.h> // sprintf
51
+ #include <stdlib.h> // atoi
52
+ #include <math.h> // frexp
53
+
54
+ int get_exp1(double x)
55
+ {
56
+ return ((*(long long *)&x) >> 52 & 0x7ff) - 1023;
57
+ }
58
+
59
+ int get_exp2(double x)
60
+ {
61
+ char buf[28];
62
+ sprintf(buf, "%+.13a", x);
63
+ puts(buf);
64
+ return atoi(buf + 19);
65
+ }
66
+
67
+ int get_exp3(double x)
68
+ {
69
+ int exp;
70
+ frexp(x, &exp);
71
+ return exp - 1;
72
+ }
73
+
74
+ int main(void)
75
+ {
76
+ double d;
77
+ while (printf(">> "), scanf("%lf", &d) == 1) {
78
+ printf("%d\n", get_exp1(d));
79
+ printf("%d\n", get_exp2(d));
80
+ printf("%d\n", get_exp3(d));
81
+ }
82
+ }
45
83
  ```

1

frexpバージョンのコードを追加

2020/05/26 12:42

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -25,4 +25,21 @@
25
25
  printf("%d\n", get_exp2(f));
26
26
  }
27
27
  }
28
+ ```
29
+
30
+ **追記**
31
+ <math.h> の frexp (これは doulbe用) を忘れていました。
32
+ float 用は frexpf で、long double 用は frexpl。
33
+ 仮数部が [0.5, 1.0) の範囲での指数を返します。
34
+ float の IEEE754 の内部表現では、仮数部が [1.0, 2.0) の範囲なので、
35
+ それに合わせると、指数部が 1 小さくなります。
36
+ ```C
37
+ #include <math.h> // frexp
38
+
39
+ int get_exp3(float x)
40
+ {
41
+ int exp;
42
+ frexpf(x, &exp);
43
+ return exp - 1;
44
+ }
28
45
  ```