Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

Unexpected floor division with ndarrays on python 3

未關閉
#275 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

評估

難度
4/5
預估耗時
3-5 天
新手友好度
25/100
Issue 類型
缺陷
描述清晰度
需要釐清
活躍度
停滯
技術堆疊
cpp, python
領域
backend

研究方向

在列出的 Python 2.7 和 3.6 設定下,使用附帶的 CMakeLists.txt 建置提供的 main.cpp,然後比較列印出的除法結果。閱讀相關的 examples/ 程式碼,並使用重現的輸出來判斷 Python 3 的行為是否符合預期,以及是否存在受支援的非向下取整除法路徑;完成的標準是取得 maintainer 確認的解釋,或精確識別出的 fix。

由索引模型根據 Issue 內容生成。

描述

Our primarily C++ code base uses an embedded python to do computation with help from boost::python. We are in the process of porting to python 3. We have noticed that it appears that the / operator when acting on a pair of boost::python::numpy::ndarray's yields floor division. That is to say the results are numerically consistent with constructing the same arrays in a python interpreter and then performing arr1 // arr2. We do did not see this behaviour when linking against python27.dll. To make my issue concrete I prepared an example based on those provided in the examples/ folder. It was built on windows 10 using:

  • MSVC 2015
  • Python 2.7.16
  • Python 3.6.8
  • cmake 3.16
  • Ninja 1.9.0
  • Boost 1.70.0

main.cpp was:

#include <boost/python/numpy.hpp>
#include <iostream>

namespace p = boost::python;
namespace np = boost::python::numpy;

typedef float arr_dtype;

int main(int argc, char **argv)
{
  Py_Initialize();
  np::initialize();

  arr_dtype raw_array1[] = {1.53f, 2.53f, 3.53f, 4.53f};
  np::ndarray nd_array1 = np::from_data(raw_array1, np::dtype::get_builtin<arr_dtype>(),
                                        p::make_tuple(4),
                                        p::make_tuple(4),
                                        p::object());

  arr_dtype raw_array2[] = {0.1f};
  np::ndarray nd_array2 = np::from_data(raw_array2, np::dtype::get_builtin<arr_dtype>(),
                                        p::make_tuple(1),
                                        p::make_tuple(1),
                                        p::object());

  std::cout << "ndarray 1 is " << p::extract<char const *>(p::str(nd_array1)) << std::endl;
  std::cout << "ndarray 2 is " << p::extract<char const *>(p::str(nd_array2)) << std::endl;

  //

  p::object result_array_div = nd_array1 / nd_array2;

  std::cout << "operator/ division of arrays is " << p::extract<char const *>(p::str(result_array_div)) << std::endl;

  return 0;
}

For Python 27 the output when running main.exe was consistent with our expectations:

ndarray 1 is [1.53 2.53 3.53 4.53]
ndarray 2 is [0.1]
operator/ division of arrays is [15.299999 25.3      35.3      45.300003]

For Python 36 the result when running main.exe was not consistent with our (possibly misguided) expectations:

ndarray 1 is [1.53 2.53 3.53 4.53]
ndarray 2 is [0.1]
operator/ division of arrays is [15. 25. 35. 45.]

Is this expected behaviour? Is there any way to enforce non-floor division when using the / operator and python 3?

For reference the CMakeLists.txt was:

cmake_minimum_required(VERSION 3.16)

project(test_boost_numpy_division)

# version selection

if (BUILD_PY3)
   set(python_package_name "Python3")
   set(BOOST_ROOT "${BOOST_ROOT_PY3}")
   set(py_dll_path "${Python3_ROOT_DIR}/python36.dll")
   set(py_maj_min_version "36")
else()
   set(python_package_name "Python2")
   set(BOOST_ROOT "${BOOST_ROOT_PY2}")
   set(py_dll_path "C:/Windows/System32/python27.dll")
   set(py_maj_min_version "27")
endif()

set(boost_python_module_name "python${py_maj_min_version}")
set(boost_numpy_module_name "numpy${py_maj_min_version}")

# python config

find_package (${python_package_name} COMPONENTS Development REQUIRED)

# boost config

set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_LIBS OFF)

find_package(Boost REQUIRED COMPONENTS ${boost_python_module_name} ${boost_numpy_module_name} unit_test_framework)

#

add_executable(main)
target_sources(main PRIVATE main.cpp)

target_link_libraries(main ${python_package_name}::Python)
target_link_libraries(main Boost::${boost_python_module_name} Boost::${boost_numpy_module_name})

set_target_properties( main
   PROPERTIES
   ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
   RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)

# 

file(COPY "${Boost_LIBRARY_DIRS}/" DESTINATION "${CMAKE_BINARY_DIR}/bin")
file(COPY "${py_dll_path}" DESTINATION "${CMAKE_BINARY_DIR}/bin")
主要語言
C++
星號
537
分支
223
平均合併
11 小時 22 分鐘
30 天內合併 PR
2

環境準備

我們還沒有檢查這個專案的環境設定檔。先看它的 README,通用步驟見我們的新手貢獻指南。

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

boostorg/python 的其他 Issue

查看 boostorg/python 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。