回答編集履歴

6

補足3を追加

2015/12/13 01:40

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -33,4 +33,9 @@
33
33
  ---
34
34
  補足2: strtofが正確なのかについて
35
35
 
36
- 2進数などの基数が2の乗数の場合、16進数表記であれば正確に解釈されます(N1570 §7.22.1.3 5 p.343参照)。しかし、これも基数が2の乗数で無い場合は、別途規定されており(N1570 §7.22.1.3 8 p.343参照)、正確に解釈できないため、その環境における丸め込みが行われます。上記の補足で述べた区別できる十分な桁数であれば丸め込みが起きても元々の情報から抜け落ちが発生するかどうかの規定は見受けられませんでしたが、「区別できる十分な桁数」という表現からすると、丸め込みが発生しても保持されるのに十分という解釈もできるかも知れません。2進数ではないC言語の実装系が手元に無い(というか、私は一度も見たこと無い)ので、詳しい検証はできていません。
36
+ 2進数などの基数が2の乗数の場合、16進数表記であれば正確に解釈されます(N1570 §7.22.1.3 5 p.343参照)。しかし、これも基数が2の乗数で無い場合は、別途規定されており(N1570 §7.22.1.3 8 p.343参照)、正確に解釈できないため、その環境における丸め込みが行われます。上記の補足で述べた区別できる十分な桁数であれば丸め込みが起きても元々の情報から抜け落ちが発生するかどうかの規定は見受けられませんでしたが、「区別できる十分な桁数」という表現からすると、丸め込みが発生しても保持されるのに十分という解釈もできるかも知れません。2進数ではないC言語の実装系が手元に無い(というか、私は一度も見たこと無い)ので、詳しい検証はできていません。
37
+
38
+ ---
39
+ 補足3: NaNは保証できない
40
+
41
+ IEEE 754-2008では、NaNについてsignaling NaNとquiet NaNの2種類を区別するようになっていますが、C言語の仕様ではそのような区別が存在しないため、区別することができません。また、符号ビットや仮数部(ただし、全て0ではない)について任意の値が可能ですが、いずれの値もNaNと解釈され、C言語上では区別することができません。ビット列が異なるにもかかわらず、上記のprintfなどを用いた方法では"nan"としか表示できませんし、逆もまた同じで、strtofでNaNの時の各ビットを指定する方法がありません。つまり、この方法では精度を落とさずC言語上での**同じ意味**にすることはできますが、必ず**同じビット列**にできる方法ではありません。

5

補足2を追加

2015/12/13 01:40

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -30,4 +30,7 @@
30
30
 
31
31
  ほとんどの実装では浮動小数点数に2進数を用いており、このような2の乗数が基数の場合は16進数でも正確に表現できるため問題にはなりません。しかし、C言語では2進数でなければならないという制限はないため、16進数であっても正確に表現できるとは限りません。その場合については、別途規定されており、double型において区別するのに十分な(sufficient to distinguish values of type double)桁数とされています。詳しくは、[C11仕様書(draft) N1570](http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf) §7.21.6.1 8 a,A p.313-314をご参考下さい。
32
32
 
33
+ ---
34
+ 補足2: strtofが正確なのかについて
33
35
 
36
+ 2進数などの基数が2の乗数の場合、16進数表記であれば正確に解釈されます(N1570 §7.22.1.3 5 p.343参照)。しかし、これも基数が2の乗数で無い場合は、別途規定されており(N1570 §7.22.1.3 8 p.343参照)、正確に解釈できないため、その環境における丸め込みが行われます。上記の補足で述べた区別できる十分な桁数であれば丸め込みが起きても元々の情報から抜け落ちが発生するかどうかの規定は見受けられませんでしたが、「区別できる十分な桁数」という表現からすると、丸め込みが発生しても保持されるのに十分という解釈もできるかも知れません。2進数ではないC言語の実装系が手元に無い(というか、私は一度も見たこと無い)ので、詳しい検証はできていません。

4

補足について補強

2015/12/12 01:07

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -1,7 +1,7 @@
1
1
  C99以降であればstrtofとprintf系のa/Aを用いることで、16進数表記(バイナリ表記)でやりとりできます。
2
2
  [cppref: strtof, strtod, strtold](http://en.cppreference.com/w/c/string/byte/strtof)
3
3
  [cppref: printf, fprintf, sprintf, snprintf, printf_s, fprintf_s](http://en.cppreference.com/w/c/io/fprintf)
4
- printf系では普通の10進数小数点数表記以外に`a`または`A`を使うと16進数表記にすることができます。この表記は標準の桁数がその型が持つ精度を**正確に(exact)**表現できる桁数となっており、(桁数を設定しない限り)精度や進数の違いにより**情報が落ちることはありません**。そして、strtofはその16進数表記をそのまま解釈して変換できます。strtofは-0やinf、nanにも対応しているのでそちらも問題ありません。なお、doubleとlong doubleも同様にできます。
4
+ printf系では普通の10進数小数点数表記以外に`a`または`A`を使うと16進数表記にすることができます。この表記は標準の桁数がその型が持つ精度を**正確に(exact)**表現できる桁数(基数が2以外の場合は補足参考)となっており、(桁数を設定しない限り)精度や進数の違いにより**情報が落ちることはありません**。そして、strtofはその16進数表記をそのまま解釈して変換できます。strtofは-0やinf、nanにも対応しているのでそちらも問題ありません。なお、doubleとlong doubleも同様にできます。
5
5
 
6
6
  変換を確認できるかも知れないサンプルコード(なぜかC11)
7
7
  ```C
@@ -28,6 +28,6 @@
28
28
  ---
29
29
  補足: FLT_RADIX(floatとかの基数)が2の乗数以外の場合
30
30
 
31
- ほとんどの実装では浮動小数点数に2進数を用いており、このような2の乗数が基数の場合は16進数でも正確に表現できるため問題にはなりません。しかし、C言語では2進数でなければならないという制限はないため、16進数であっても正確に表現できるとは限りません。その場合については、別途規定されており、double型において区別するのに十分な(sufficient to distinguish values of type double)桁数とされています。詳しくは、[C11仕様書(draft) N1570](http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf) §7.21.6.1 p.313-314をご参考下さい。
31
+ ほとんどの実装では浮動小数点数に2進数を用いており、このような2の乗数が基数の場合は16進数でも正確に表現できるため問題にはなりません。しかし、C言語では2進数でなければならないという制限はないため、16進数であっても正確に表現できるとは限りません。その場合については、別途規定されており、double型において区別するのに十分な(sufficient to distinguish values of type double)桁数とされています。詳しくは、[C11仕様書(draft) N1570](http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf) §7.21.6.1 8 a,A p.313-314をご参考下さい。
32
32
 
33
33
 

3

2進数では無い場合

2015/12/12 00:50

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -23,4 +23,11 @@
23
23
  }
24
24
  return 0;
25
25
  }
26
- ```
26
+ ```
27
+
28
+ ---
29
+ 補足: FLT_RADIX(floatとかの基数)が2の乗数以外の場合
30
+
31
+ ほとんどの実装では浮動小数点数に2進数を用いており、このような2の乗数が基数の場合は16進数でも正確に表現できるため問題にはなりません。しかし、C言語では2進数でなければならないという制限はないため、16進数であっても正確に表現できるとは限りません。その場合については、別途規定されており、double型において区別するのに十分な(sufficient to distinguish values of type double)桁数とされています。詳しくは、[C11仕様書(draft) N1570](http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf) §7.21.6.1 p.313-314をご参考下さい。
32
+
33
+

2

より正確に表現

2015/12/12 00:46

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -1,7 +1,7 @@
1
1
  C99以降であればstrtofとprintf系のa/Aを用いることで、16進数表記(バイナリ表記)でやりとりできます。
2
2
  [cppref: strtof, strtod, strtold](http://en.cppreference.com/w/c/string/byte/strtof)
3
3
  [cppref: printf, fprintf, sprintf, snprintf, printf_s, fprintf_s](http://en.cppreference.com/w/c/io/fprintf)
4
- printf系では普通の10進数小数点数表記以外に`a`または`A`を使うと16進数表記にすることができます。この表記は標準の桁数がその型が持つ精度と同じになっており、(桁数を設定しない限り)精度や進数の違いにより**情報が落ちることはありません**。そして、strtofはその16進数表記をそのまま解釈して変換できます。strtofは-0やinf、nanにも対応しているのでそちらも問題ありません。なお、doubleとlong doubleも同様にできます。
4
+ printf系では普通の10進数小数点数表記以外に`a`または`A`を使うと16進数表記にすることができます。この表記は標準の桁数がその型が持つ精度を**正確(exact)**表現できる桁数となっており、(桁数を設定しない限り)精度や進数の違いにより**情報が落ちることはありません**。そして、strtofはその16進数表記をそのまま解釈して変換できます。strtofは-0やinf、nanにも対応しているのでそちらも問題ありません。なお、doubleとlong doubleも同様にできます。
5
5
 
6
6
  変換を確認できるかも知れないサンプルコード(なぜかC11)
7
7
  ```C

1

説明の仕方を変えた

2015/12/11 22:38

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -1,7 +1,7 @@
1
- C99以降であればstrtofとprintf系のa/Aが使用できます。
1
+ C99以降であればstrtofとprintf系のa/Aいること、16進数表記(バイナリ表記)でやりとりできます。
2
2
  [cppref: strtof, strtod, strtold](http://en.cppreference.com/w/c/string/byte/strtof)
3
3
  [cppref: printf, fprintf, sprintf, snprintf, printf_s, fprintf_s](http://en.cppreference.com/w/c/io/fprintf)
4
- printf系では普通の10進数小数点数表記以外に`a`または`A`を使うと16進数表記(バイナリ表記)にすることができます。この表記は標準の桁数がその型が持つ精度と同じになっており、(桁数を設定しない限り)精度や進数の違いにより**情報が落ちることはありません**。そして、strtofはその16進数表記をそのまま解釈して変換できます。strtofは-0やinf、nanにも対応しているのでそちらも問題ありません。なお、doubleとlong doubleも同様にできます。
4
+ printf系では普通の10進数小数点数表記以外に`a`または`A`を使うと16進数表記にすることができます。この表記は標準の桁数がその型が持つ精度と同じになっており、(桁数を設定しない限り)精度や進数の違いにより**情報が落ちることはありません**。そして、strtofはその16進数表記をそのまま解釈して変換できます。strtofは-0やinf、nanにも対応しているのでそちらも問題ありません。なお、doubleとlong doubleも同様にできます。
5
5
 
6
6
  変換を確認できるかも知れないサンプルコード(なぜかC11)
7
7
  ```C