8

奇妙なことに、Python の math モジュールのすべての関数は Decimal オブジェクトで問題なく動作するようです。例: frexp、exp、cos。

と入力するとprint(math.frexp(decimal.Decimal('2341.12412')))、Python は正しい答えである を出力し、(0.57156... , 12)例外をスローしません。

数学モジュールは低レベルの C で書かれ、効率のためにハードウェアの数学演算にできるだけ大きく依存していると思います。では、なぜ Decimal オブジェクトで機能するのでしょうか?

数学関数に型チェックを入れ、引数が Decimal の場合は別の実装に切り替えましたか? ドキュメントに記載されているようなものは見当たりませんでした。Decimal が自動的に float に変換されている可能性もありますが、それも意味がありません。

ええ、私は混乱しています。

4

1 に答える 1

7

よく見ると、math module.c私はこれを得ました:

static PyObject *
math_frexp(PyObject *self, PyObject *arg)
{
    int i;
    double x = PyFloat_AsDouble(arg);
    if (x == -1.0 && PyErr_Occurred())
        return NULL;
    /* deal with special cases directly, to sidestep platform
       differences */
    if (Py_IS_NAN(x) || Py_IS_INFINITY(x) || !x) {
        i = 0;
    }
    else {
        PyFPE_START_PROTECT("in math_frexp", return 0);
        x = frexp(x, &i);
        PyFPE_END_PROTECT(x);
    }
    return Py_BuildValue("(di)", x, i);
}

コードを見ると、実際にはfloat( PyFloat_AsDouble)を使用しています。

についても同じことが言えますexp

static PyObject *
math_factorial(PyObject *self, PyObject *arg)
{
    long x;
    PyObject *result, *odd_part, *two_valuation;

    if (PyFloat_Check(arg)) {
        PyObject *lx;
        double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg);
        if (!(Py_IS_FINITE(dx) && dx == floor(dx))) {
            PyErr_SetString(PyExc_ValueError,
                            "factorial() only accepts integral values");
            return NULL;
        }
        lx = PyLong_FromDouble(dx);
        if (lx == NULL)
            return NULL;
        x = PyLong_AsLong(lx);
        Py_DECREF(lx);
.........................................................
于 2013-04-06T03:44:08.290 に答える