двойное преобразование PyFloat неверно

Я изучаю SWIG, для использования C в Python. Я написал эту функцию, но я не могу понять, почему wrapped myfunc возвращает неверные значения float / double:

mfuncs.c

 #include <stdlib.h> float myfunc(int n) { float result; result = 100 / n; return result; } 

mfuncs.i

 %module mfuncs %typemap(out) double, float "$result = PyFloat_FromDouble($1);" extern float myfunc(int n); 

Наконец, я получаю 1107558400.0 вместо 33.33333.

 >>> импорт mfuncs
 >>> mfuncs.myfunc (3)
 +1107558400,0
 >>> 

Где ошибка?

2 Solutions collect form web for “двойное преобразование PyFloat неверно”

Карта типов SWIG не нужна – она ​​предоставляется по умолчанию, вам нужно только написать typemaps для «эзотерических» типов, а предоставленные по умолчанию double / float .

Настоящая проблема заключается в том, что вы не компилируете с включенными предупреждениями или игнорируете их! На самом деле стоит привыкнуть к компиляции с помощью «-Wall -Wextra» или независимо от того, что ваш компилятор требует, чтобы включить максимальные предупреждения и прислушаться к ним.

Ваш SWIG-интерфейс сообщает SWIG о функции myfunc но в этом интерфейсе нет ничего, чтобы сделать объявление доступным компилятору, который вы используете для компиляции сгенерированного myfuncs_wrap.c. Это означает, что когда вы приходите, чтобы скомпилировать общую библиотеку, вы полагаетесь на неявное объявление myfunc . GCC на моей машине с -Wall сообщает об этом:

test_wrap.c: 3139: 3: warning: неявное объявление функции 'myfunc'

Неявное объявление предполагает, что оно возвращает int . Это просто правило в C, если нет объявления, это как если бы вы написали:

 #include <stdlib.h> int myfunc(int n); int main() { printf("%d\n", myfunc(3)); return 0; } 

что явно неверно (неопределенное поведение, если быть точным), учитывая, что определение myfunc возвращает float . Ваша реализация (юридически) решает сделать простейшую вещь для этого неопределенного поведения, которое примерно побитно отбрасывается из int в float . (Он может одинаково хорошо делать что-либо , даже что-то другое в каждом прогоне – вот красота неопределенного поведения).

Вы можете исправить свой интерфейс SWIG, изменив его на:

 %module mfuncs %{ extern float myfunc(int n); %} extern float myfunc(int n); 

это работает, потому что код между %{ и %} напрямую передается сгенерированной оболочке, что делает компилятор осведомленным о реальном объявлении myfunc при создании обертки.

В моем представлении есть более приятное решение: предоставить объявление только один раз, в заголовочном файле, а затем ваш файл интерфейса будет выглядеть следующим образом:

 %module mfuncs %{ #include "myfunc.h" %} %include "myfunc.h" 

(и, очевидно, #include "myfunc.h" в myfunc.c). Таким образом, вы только записываете декларацию один раз, и компилятор будет предупреждать / ошибочно, если есть что-то, что не совсем ожидаемо, а не просто взять (как правило, неверное) лучшее предположение.

У вас есть две ошибки в этом коде, которые не позволяют myfunc(3) вернуть этот 33.3333, который вы ожидаете. Флексо прекрасно объяснил проблему упаковки. Другой проблемой является эта линия

  result = 100 / n; 

100 – это int, n – int, результатом деления будет int, а THEN – float. Итак, myfunc(3) == 33. Python 2 действует одинаково, он был изменен в Python 3 таким образом, что разделение двух ints приводит к поплавке.

Просто измените эту строку на

  result = 100.0 / n; 

или сделать n float / double.

  • Есть ли хороший способ подготовить документацию для интерфейсов swig?
  • Передача bool по ссылке с помощью SWIG и Python
  • Время жизни временных объектов в SWIP-пакетах Python (?)
  • Как применять шаблоны типов SWIG OUTPUT для типов классов в Python?
  • Как сделать SWIG в VS2010?
  • Преобразование std :: vector в массив NumPy без копирования данных
  • структура каталога для проекта, который смешивает C ++ и Python
  • Быстрое преобразование вектора C / C ++ в массив Numpy
  •  
    Interesting Posts for Van-Lav

    Python: получить список всех файлов и папок в каталоге, время создания, время последней модификации. Системно-независимое решение?

    Добавление элементов в список, если это не функция

    Печать ПОЛНОГО содержимого массива numpy

    Что такое интерфейс для итераторов python?

    закрытие протоколов python и выход приложения

    Когда использовать метод каскадирования в Python?

    Выполнение скрипта python в эмуляторе терминала Android

    Возможная оптимизация для расчета квадратичного евклидова расстояния

    Настройте зону покрытия.py для использования миграции

    объединяющие множества, которые имеют хотя бы один общий элемент

    Недопустимое исключение аргумента в socket.accept (), если я перезапускаю сразу после предыдущего запуска quit

    Башни Ханоя Python – понимание рекурсии

    Несколько входов с одного входа

    Сценарий Python для exe на python 3.5

    OpenCV: преобразование из NumPy в IplImage в Python

    Python - лучший язык программирования в мире.