Python C/API Tutorial 3.1.1 Numbers

今日も C/API で遊んでいます. 最後の round に苦労したけど, おかげでモジュールあたりに詳しくなりました.

#include <Python.h>

void code1()
{
    PyObject *result;

    result = PyNumber_Add(PyInt_FromLong(2), PyInt_FromLong(2));
    PySys_WriteStdout(">>> 2+2\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    // This is a comment
    PySys_WriteStdout(">>> # This is a comment\n");
    result = PyNumber_Add(PyInt_FromLong(2), PyInt_FromLong(2));
    PySys_WriteStdout("... 2+2\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    result = PyNumber_Add(PyInt_FromLong(2), PyInt_FromLong(2)); // and a comment on the same line as code
    PySys_WriteStdout(">>> 2+2  # and a comment on the same line as code\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));


    result = PyNumber_Divide(PyNumber_Subtract(PyInt_FromLong(50),
                                               PyNumber_Multiply(
                                                   PyInt_FromLong(5),
                                                   PyInt_FromLong(6))),
                             PyInt_FromLong(4));
    PySys_WriteStdout(">>> (50-5*6)/4\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    // Integer division returns the floor:
    PySys_WriteStdout(">>> # Integer division returns the floor:\n");
    result = PyNumber_Divide(PyInt_FromLong(7), PyInt_FromLong(3));
    PySys_WriteStdout("... 7/3\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    result = PyNumber_Divide(PyInt_FromLong(7), PyInt_FromLong(-3));
    PySys_WriteStdout(">>> 7/-3\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    return;
}

void code2()
{
    PyObject *width = PyInt_FromLong(20);
    PySys_WriteStdout(">>> width = 20\n");

    PyObject *height = PyNumber_Multiply(PyInt_FromLong(5), PyInt_FromLong(9));
    PySys_WriteStdout(">>> height = 5*9\n");

    PyObject *result = PyNumber_Multiply(width, height);
    PySys_WriteStdout(">>> width * height\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    return;
}

void code3()
{
    PyObject *x, *y, *z;

    x = y = z = PyInt_FromLong(0); // Zero x, y and z
    PySys_WriteStdout(">>> x = y = z = 0  # Zero x, y and z\n");

    PySys_WriteStdout(">>> x\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(x));

    PySys_WriteStdout(">>> y\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(y));

    PySys_WriteStdout(">>> z\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(z));
}

void code4()
{
    PySys_WriteStdout(">>> # try to access an undefined variable\n"
                      "... n\n");
    PyRun_SimpleString("n");
}

void code5()
{
    PyObject *result;

    result = PyNumber_Divide(PyNumber_Multiply(PyInt_FromLong(3),
                                               PyFloat_FromDouble(3.75)),
                             PyFloat_FromDouble(1.5));
    PySys_WriteStdout(">>> 3 * 3.75 / 1.5\n");
    PySys_WriteStdout("%1.1f\n", PyFloat_AsDouble(result));

    result = PyNumber_Divide(PyFloat_FromDouble(7.0), PyInt_FromLong(2));
    PySys_WriteStdout(">>> 7.0 / 2\n");
    PySys_WriteStdout("%1.1f\n", PyFloat_AsDouble(result));
}

void code6()
{
    PyObject *onej = PyComplex_FromDoubles(0, 1);
    PyObject *oneJ = PyComplex_FromDoubles(0, 1);

    Py_complex result;
    PyObject *po_result;

    po_result = PyNumber_Multiply((PyObject *)onej, (PyObject *)oneJ);
    result = PyComplex_AsCComplex(po_result);
    PySys_WriteStdout(">>> 1j * 1J\n");
    PySys_WriteStdout("(%.0f+%.0fj)\n", result.real, result.imag);

    po_result = PyNumber_Multiply(onej,
                                  PyComplex_FromDoubles(0, 1));
    result = PyComplex_AsCComplex(po_result);
    PySys_WriteStdout(">>> 1j * complex(0,1)\n");
    PySys_WriteStdout("(%.0f+%.0fj)\n", result.real, result.imag);

    po_result = PyNumber_Add(PyInt_FromLong(3),
                             PyNumber_Multiply(onej,
                                               PyInt_FromLong(3)));
    result = PyComplex_AsCComplex(po_result);
    PySys_WriteStdout(">>> 3+1j*3\n");
    PySys_WriteStdout("(%.0f+%.0fj)\n", result.real, result.imag);

    po_result = PyNumber_Multiply(PyComplex_FromDoubles(3, 1),
                                  PyComplex_FromDoubles(3, 0));
    result = PyComplex_AsCComplex(po_result);
    PySys_WriteStdout(">>> (3+1j)*3\n");
    PySys_WriteStdout("(%.0f+%.0fj)\n", result.real, result.imag);

    po_result = PyNumber_Divide(PyComplex_FromDoubles(1, 2),
                                PyComplex_FromDoubles(1, 1));
    result = PyComplex_AsCComplex(po_result);
    PySys_WriteStdout(">>> (1+2j)/(1+1j)\n");
    PySys_WriteStdout("(%1.1f+%1.1fj)\n", result.real, result.imag);
}

void code7()
{
    PyObject *a = PyComplex_FromDoubles(1.5, 0.5);
    PySys_WriteStdout(">>> a=1.5+0.5j\n");
    PySys_WriteStdout(">>> a.real\n");
    PySys_WriteStdout("%1.1f\n", PyComplex_RealAsDouble(a));
    PySys_WriteStdout(">>> a.imag\n");
    PySys_WriteStdout("%1.1f\n", PyComplex_ImagAsDouble(a));
}

void code8()
{
    PyObject *a = PyComplex_FromDoubles(3, 4);
    PyObject *a_as_float;

    PySys_WriteStdout(">>> a=3.0+4.0j\n");
    a_as_float = PyNumber_Float(a);
    PySys_WriteStdout(">>> float(a)\n");
    if (a_as_float == NULL) {
        PySys_WriteStdout("Traceback (most recent call last):\n"
                          "  File \"<stdin>\", line 1, in ?\n"
                          "TypeError: can't convert complex to float; use abs(z)\n");
    } else {
        PySys_WriteStdout("%f\n", PyFloat_AsDouble(a_as_float));
    }

    PySys_WriteStdout(">>> a.real\n");
    PySys_WriteStdout("%1.1f\n", PyComplex_RealAsDouble(a));

    PySys_WriteStdout(">>> a.imag\n");
    PySys_WriteStdout("%1.1f\n", PyComplex_ImagAsDouble(a));

    PySys_WriteStdout(">>> abs(a)  # sqrt(a.real**2 + a.imag**2)\n");
    PySys_WriteStdout("%1.1f\n", PyFloat_AsDouble(PyNumber_Absolute(a)));
}

void code9()
{
    PyObject *_, *tax, *price;
    PyObject *builtin, *round;
    PyObject *dict;
    PyObject *args;

    tax = PyNumber_Divide(PyFloat_FromDouble(12.5), PyInt_FromLong(100));
    PySys_WriteStdout(">>> tax = 12.5 / 100\n");

    price = PyFloat_FromDouble(100.50);
    PySys_WriteStdout(">>> price = 100.50\n");

    _ = PyNumber_Multiply(price, tax);
    PySys_WriteStdout(">>> price * tax\n");
    PySys_WriteStdout("%2.4f\n", PyFloat_AsDouble(_));

    _ = PyNumber_Add(price, _);
    PySys_WriteStdout(">>> price + _\n");
    PySys_WriteStdout("%3.4f\n", PyFloat_AsDouble(_));

    PyImport_ImportModule("__builtin__");
    builtins = PyEval_GetBuiltins();
    round = PyDict_GetItemString(builtins, "round");

    args = PyTuple_Pack(2, _, PyInt_FromLong(2));
    _ = PyObject_CallObject(round, args);
    PySys_WriteStdout(">>> round(_, 2)");
    PySys_WriteStdout("%3.2f\n", PyFloat_AsDouble(_));
}

int main(void)
{
    Py_Initialize();
    code1();
    code2();
    code3();
    code4();
    code5();
    code6();
    code7();
    code8();
    code9();

    Py_Finalize();
    return 0;
}

Comments

blog comments powered by Disqus

Licenses