2016-05-12 9 views
2

フロートアンダーフローを扱うC Primer Plus演習の1つを解いています。タスクは、それをシミュレートすることです。Cのフロートアンダーフロー説明

#include<stdio.h> 
#include<float.h> 

int main(void) 
{ 
    // print min value for a positive float retaining full precision 
    printf("%s\n %.150f\n", "Minimum positive float value retaining full precision:",FLT_MIN); 

    // print min value for a positive float retaining full precision divided by two 
    printf("%s\n %.150f\n", "Minimum positive float value retaining full precision divided by two:",FLT_MIN/2.0); 

    // print min value for a positive float retaining full precision divided by four 
    printf("%s\n %.150f\n", "Minimum positive float value retaining full precision divided by four:",FLT_MIN/4.0); 

    return 0; 
} 

結果は、私が2と4で分float値の除算のための低い精度を期待したが、それは精度がOKで、アンダーフロー状況が存在しないようです

Minimum positive float value retaining full precision:     0.000000000000000000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625000000000000000000000000 
Minimum positive float value retaining full precision divided by two: 0.000000000000000000000000000000000000005877471754111437539843682686111228389093327783860437607543758531392086297273635864257812500000000000000000000000 
Minimum positive float value retaining full precision divided by four: 0.000000000000000000000000000000000000002938735877055718769921841343055614194546663891930218803771879265696043148636817932128906250000000000000000000000 

です:私はこのようにそれをやりました。どのように可能ですか?私は何か見落としてますか?

ありがとうございました

+0

引数を参照してください。 –

+0

@Kerrek SBあなたのコメントは本当ですが、コードがIEEE 754 [binary32](https://en.wikipedia.org/wiki/Single-precision_floating-point_format)を使用していた場合、OPのいわゆる「精度があまり期待できません」には影響しません)。 – chux

答えて

1

2.

によってコードの単純な除算FLT_MIN(2の確かにパワー)としての精度を評価する誤った方法の代わりにこれだけの2のべき乗の上にある数字で始めますそのバイナリsignificand1.000...(maybe total of 24 binary digits)...0001のようなものです。保証値は元々floatです。 (FLT_MIN/2.0doubleある。)数値未満FLT_MINなったときに精度が失われることを以下

注意:最小正規正の浮動小数点数。

FLT_TRUE_MIN:最小の正の浮動小数点数も考慮してください。プロトタイプで関数のパラメータに一致するデフォルトのプロモーションを受けないbinary32

#include <float.h> 
#include <math.h> 
#include <stdio.h> 

int main(void) { 
    char *format = "%.10e %a\n"; 
    printf(format, FLT_MIN, FLT_MIN); 
    printf(format, FLT_TRUE_MIN, FLT_TRUE_MIN); 

    float f = nextafterf(1.0f, 2.0f); 
    do { 
    f /= 2; 
    printf(format, f, f); // print in decimal and hex for detail 
    } while (f); 
    return 0; 
} 

出力

1.1754943508e-38 0x1p-126 
1.4012984643e-45 0x1p-149 

5.0000005960e-01 0x1.000002p-1 
2.5000002980e-01 0x1.000002p-2 
1.2500001490e-01 0x1.000002p-3 
... 
2.3509889819e-38 0x1.000002p-125 
1.1754944910e-38 0x1.000002p-126 
5.8774717541e-39 0x1p-127 // lost least significant bit of precision 
2.9387358771e-39 0x1p-128 
... 
2.8025969286e-45 0x1p-148 
1.4012984643e-45 0x1p-149 
0.0000000000e+00 0x0p+0