13

次の C コードを検討してください。

#include <stdio.h>
int main(int argc, char* argv[]) 
{
    const long double ld = 0.12345678901234567890123456789012345L;
    printf("%lu %.36Lf\n", sizeof(ld), ld);
    return 0;
}

gcc 4.8.1の下でコンパイルするとUbuntu x64 13.04、次のように出力されます。

16 0.123456789012345678901321800735590983

これは、long double の重みが 16 バイトであることを示していますが、小数は 20 位までしか問題ないようです。それはどのように可能ですか?16 バイトはクワッドに対応し、クワッドは 33 から 36 の小数を与えます。

4

4 に答える 4

12

C 実装のlong double形式は、符号が 1 ビット、指数が 15 ビット、仮数が 64 ビット (合計 10 バイト) の Intel 形式を使用します。コンパイラはこれに 16 バイトを割り当てます。これは無駄ですが、アラインメントなどには役立ちます。ただし、64 ビットでは log 10 (2 64 ) 桁の有効桁しか提供されず、これは約 20 桁です。

于 2013-06-29T17:33:46.133 に答える
4

のさまざまな C 実装には、long doubleバリアントの範囲と精度がある場合があります。基礎となる浮動小数点表記へのsizeofヒントはありますが、それを指定していません。Along doubleは 33 から 36 の小数である必要はありません。とまったく同じ表現を持つことさえできdoubleます。

精度をハードコーディングせずに、利用可能なすべての精度を使用し、無理をしないことをお勧めします。

const long double ld = 0.12345678901234567890123456789012345L;
printf("%.*Le\n", LDBL_DIG + 3, ld);
printf("%.*Le\n", LDBL_DIG + 3, nextafterl(ld, ld*2));

もちろん、これは(私のEclipse Intel 64ビットで)出力されますが、あなたのものは異なる場合があります。

1.234567890123456789013e-01
1.234567890123456789081e-01

[編集]

レビューでは、+2で十分です。を使用することをお勧めしますLDBL_DECIMAL_DIG浮動小数点値の精度を維持するには、Printf 幅指定子を参照してください。

printf("%.*Le\n", (LDBL_DIG + 3) - 1, ld);
printf("%.*Le\n", LDBL_DECIMAL_DIG - 1, ld);
于 2013-06-29T19:30:21.617 に答える
0

このsizeof演算子は、データ型のサイズをバイト単位で返します。浮動小数点形式の型は、データ型のバイト サイズと実際には比較できません。それ以外は、通常、サイズが大きいほど精度が高くなります。

于 2013-06-29T17:32:48.400 に答える