私はこの質問に答えようとしていました。浮動小数点数fの各桁の値を出力する関数print_dig_float(float f)を記述します。たとえば、fが2345.1234の場合、print_dig_float(f)は、2、3、4、5、1、2、3、および4桁の整数値を連続して出力します。
私がしたことは、小数点以下の桁数が与えられた場合、10を掛けて数字を左に移動しようとします(例:3.45-> 345)。その後、余りを取り、各数字を配列に格納します。要素に入れます。次に、それらを印刷します。
したがって、私のプログラムは次のようになります。
#include <stdio.h>
void print_dig_float(float f);
int main(int argc, char const *argv[]) {
print_dig_float(23432.214122);
return 0;
}
void print_dig_float(float f) {
printf("%f\n", f);
int i = 0, arr[50], conv;
//move digits to the left
do {
f = f * 10;
conv = f;
printf("%i\n", conv);
} while (conv % 10 != 0);
conv = f / 10;
//store digits in an array
while (conv > 1) {
arr[i] = conv % 10;
conv = conv / 10;
i++;
}
for (int j = i - 1; j >= 0; j--) {
printf("%i ", arr[j]);
}
printf("\n");
}
私が番号23432.214122でそれをテストしたとき、これは私が得るものです(Linuxターミナルによると):
23432.214844
234322
2343221
23432216
234322160
2 3 4 3 2 2 1 6
問題は、上記のように、私が何かをする前であっても、コンピューターが数値の末尾の10進数を任意に変更することです。これが私のせいなのか、この問題に対するコンピューターのせいなのかわかりません。
C 2018 5.2.4.2.2によると、浮動小数点数は、符号、ある指数への固定底、およびその底の数字で形成された数字で表されます。最も一般的には、2つがベースとして使用されます。
底が2の場合、表現可能なすべての数値は必然的に底の累乗の整数倍(負の累乗の可能性がある)であるため、23432.214122を浮動小数点で表すことはできません。23432.214122が1/2の倍数でない1/4、⅛1/2 4 1/2、5、またはこれらの任意の他の電源。
23432.214122
がソースコードで使用される場合、表現可能な値に変換されます。適切なC実装では、最も近い表現可能な値が使用されますが、C標準では、最も近い大きい値または最も近い小さい値のいずれかを使用できます。これ以外に、表示される数字は任意ではありません。それらは数学の結果です。
IEEE-754 binary32がに使用される場合float
、23432.214122に最も近い表現可能な値は正確に23432.21484375です。
なぜなら、C実装が浮動小数点数に2進数を使用する場合、浮動小数点数には2進数があり、10進数がないからです。一般に、10進数を持たないものから10進数を抽出しようとすることは意味がありません。浮動小数点形式の影響を受ける制限まで、元の数値であった10進数を判別することができます。ただし、「23432.214122」の桁数が多すぎるため、32ビット浮動小数点型ではこれを実行できません。一般的に使用されている64ビットタイプの場合double
、最初に小数点以下の桁数がわかっていれば、元の桁を復元できます。通常、その情報がないと元の数字を復元することはできません。これまで見てきたように、末尾の数字は異なり、浮動小数点数自体には違いがどこから始まるかが示されていません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加