1

Cでマシンの精度をfloatからdoubleに上げると、級数展開の項が自動的に上がるかどうか疑問に思っていました.例えば、三角関数ですか?

これとスタックオーバーフローに関する私の他の質問は、異方性媒体の波動方程式で発生する数値不安定性を調査することに関係しています。

4

2 に答える 2

5

一般に、正弦、対数などを実行するルーチンの精度に影響を与えるのは、呼び出すルーチンのバージョンです。優れた数学ライブラリには、単精度正弦 (C のsinf関数)、倍精度正弦 (C の関数) sin、および長倍精度の正弦 (C の関数) 用の個別のルーチンがありますsinlsinfC では通常、 、sin、またはへの呼び出しを記述して、これらのバージョンを明示的に呼び出しますsinl。C は も提供します<tgmath.h>。これにより、ソース コードsin(x)は のタイプに応じて特定のバージョンに展開されxます。C++ では、変数の型に応じて関数呼び出しも解決されます。

優れた数学ライブラリでは、sinfルーチンは の精度に適した精度の高速なアルゴリズムを使用し、 の精度にfloat適しsinた低速のアルゴリズムを使用しますdouble。これらのルーチンの作成は複雑な作業であるため、数学ライブラリの品質はさまざまです。

級数展開は使用しません。(特に、テイラー級数は、誤差の分布が悪く、収束に必要な項が多すぎるため使用されません。) 代わりに、慎重に準備された近似多項式が使用されます。何らかの形のミニマックス多項式がよく使用されます。より正確な型のルーチンは、より多くの項を持つ多項式を使用する可能性がありますが、ドメインをより多くの間隔に分割したり、何らかの形式の拡張精度を使用したりするなど、他の方法で変更する可能性もあります。これはどれも自動ではありません。ルーチンは、ソフトウェア エンジニアによって手動で準備されます。

于 2013-04-03T12:59:29.850 に答える
0

このリファレンスによるとsin(x)、C++の関数にはさまざまなバージョンがありますが、

C では、この関数の double バージョンのみがこの名前で存在します

これを確認するために、次のコード行を書きました。

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

int main(void){

    double d = 0.12345e16;
    float f;
    f = d;

    printf("the difference is %f\n", sin(d) - sin(f));

    f = 0.12345e16;
    d = f;
    printf("the difference is now %f\n", sin(d) - sin(f));

}

これにより、次の出力が生成されます (C コンパイラでコンパイルした場合)。

the difference is 1.947785
the difference is now 0.000000

編集 - 元のコードにタイプミスがありました。更新され、期待される結果が得られました。

上記は、2 つの引数が同じ方法で評価されることを示しており、同じアルゴリズムが使用されていることを確認しています。

これは Linux で gcc コンパイラを使用し、-lmオプションと呼び出されたファイルを使用していますfltchk.c(これにより、gcc が C コンパイラを使用するようになるはずです)。

于 2013-04-03T13:08:30.400 に答える