for循环不在零参数上执行
for loop not executing on zero parameters
我是一名自学成才的 python 和 C 程序员,我现在正在努力学习 C++
作为一个小练习,我尝试移植我在我的 Python 迷你游戏中创建的一个函数,该函数生成一个 运行dom 矩阵,然后对其进行平均,以创建一个地图地形海拔。
我尝试使用 size_t 和数组的最大大小的技巧在 C++ 中实现它,我之前已经在 C 中成功使用过它。
但是,当我的 AverageSurroundings 中的 for 循环在第 0 行或第 0 列 运行 时,它似乎没有 运行。stderr 上的输出证实了这一点(我不知道如何把它放在问题中,抱歉)并导致被零除错误,这是不应该发生的。我做了一个小修复,但我找不到问题的根源
这是显示问题的最小片段。
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/assignment.hpp> //for <<=
#include <cstdint>
#include <iostream>
static const std::size_t n_rows = 3;
static unsigned int
AverageSurroundings(const boost::numeric::ublas::matrix<unsigned int> mat,
const std::size_t row, const std::size_t col) {
std::uint_fast16_t sum = 0; // <= 9*255= 2295 => 12 bits
std::uint_fast8_t count = 0;
std::cerr << "AverageSurroundings(" << row << ',' << col << ") called." << '\n';
for ( std::size_t r = row - 1; r <= row + 1; r++) {
for (std::size_t c = col - 1; c <= col + 1; c++) { // these values should remain positive, so we just
// need to check if we are smaller than n_rows,
//thanks to the wraparound of size_t.
std::cerr<<"r:"<<r<<" c:"<<c<<'\n'; // FIXME : loop not executing on first row/column
if (r < n_rows && c < n_rows) {
sum += mat(r, c);
count++;
std::cerr << "AverageSurroundings(" << row << ',' << col << "): Neighbour found at (" << r<< ',' << c << ")." <<'\n';
}
}
}
std::cerr << std::endl; // flushing and adding a blank line.
return count ? static_cast<unsigned int>(sum / count):0; // count is 8bits long so no overflow is possible, casting to silence warning.
//added ? to avoid floating point error for debug. FIXME : This should NOT BE 0
}
static const boost::numeric::ublas::matrix<unsigned int>
Average(const boost::numeric::ublas::matrix<unsigned int> mat,
const std::size_t rows) {
using boost::numeric::ublas::matrix;
matrix<unsigned int> m(n_rows, n_rows);
for (std::size_t row = 0; row < rows; row++) {
for (std::size_t col = 0; col < rows; col++) {
m(row, col) = AverageSurroundings(mat, row, col);
std::cout << m(row, col) << '\t';
}
std::cout << '\n';
}
std::cout << std::endl;
return m;
}
int main() {
using boost::numeric::ublas::matrix;
matrix<unsigned int> m(n_rows,n_rows); m <<= 0, 1, 2,
3, 4, 5,
6, 7, 8;
std::cout<< "---- RESULT ----" << '\n';
const matrix<unsigned int> m2 = Average(m, n_rows);
}
和相应的输出。
---- RESULT ----
0 0 0
0 4 4
0 5 6
欢迎就此问题提供任何帮助以及评论或代码格式。
您使用 row==0
and/or col==0
调用 AverageSurroundings
(请参阅 Average
中的循环变量)。
但是 std::size_t
是 UNSIGNED 类型...所以当它为零时,负 1,它在 AverageSurroundings
的循环中下溢并且 returns 0xFFFF FFFF FFFF FFFF
...明显大于row+1
(或col+1
)。所以循环不会执行一次。
即使没有下溢,您仍然会在矩阵之外,即使使用适当的“-1”作为索引...
我是一名自学成才的 python 和 C 程序员,我现在正在努力学习 C++
作为一个小练习,我尝试移植我在我的 Python 迷你游戏中创建的一个函数,该函数生成一个 运行dom 矩阵,然后对其进行平均,以创建一个地图地形海拔。
我尝试使用 size_t 和数组的最大大小的技巧在 C++ 中实现它,我之前已经在 C 中成功使用过它。
但是,当我的 AverageSurroundings 中的 for 循环在第 0 行或第 0 列 运行 时,它似乎没有 运行。stderr 上的输出证实了这一点(我不知道如何把它放在问题中,抱歉)并导致被零除错误,这是不应该发生的。我做了一个小修复,但我找不到问题的根源
这是显示问题的最小片段。
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/assignment.hpp> //for <<=
#include <cstdint>
#include <iostream>
static const std::size_t n_rows = 3;
static unsigned int
AverageSurroundings(const boost::numeric::ublas::matrix<unsigned int> mat,
const std::size_t row, const std::size_t col) {
std::uint_fast16_t sum = 0; // <= 9*255= 2295 => 12 bits
std::uint_fast8_t count = 0;
std::cerr << "AverageSurroundings(" << row << ',' << col << ") called." << '\n';
for ( std::size_t r = row - 1; r <= row + 1; r++) {
for (std::size_t c = col - 1; c <= col + 1; c++) { // these values should remain positive, so we just
// need to check if we are smaller than n_rows,
//thanks to the wraparound of size_t.
std::cerr<<"r:"<<r<<" c:"<<c<<'\n'; // FIXME : loop not executing on first row/column
if (r < n_rows && c < n_rows) {
sum += mat(r, c);
count++;
std::cerr << "AverageSurroundings(" << row << ',' << col << "): Neighbour found at (" << r<< ',' << c << ")." <<'\n';
}
}
}
std::cerr << std::endl; // flushing and adding a blank line.
return count ? static_cast<unsigned int>(sum / count):0; // count is 8bits long so no overflow is possible, casting to silence warning.
//added ? to avoid floating point error for debug. FIXME : This should NOT BE 0
}
static const boost::numeric::ublas::matrix<unsigned int>
Average(const boost::numeric::ublas::matrix<unsigned int> mat,
const std::size_t rows) {
using boost::numeric::ublas::matrix;
matrix<unsigned int> m(n_rows, n_rows);
for (std::size_t row = 0; row < rows; row++) {
for (std::size_t col = 0; col < rows; col++) {
m(row, col) = AverageSurroundings(mat, row, col);
std::cout << m(row, col) << '\t';
}
std::cout << '\n';
}
std::cout << std::endl;
return m;
}
int main() {
using boost::numeric::ublas::matrix;
matrix<unsigned int> m(n_rows,n_rows); m <<= 0, 1, 2,
3, 4, 5,
6, 7, 8;
std::cout<< "---- RESULT ----" << '\n';
const matrix<unsigned int> m2 = Average(m, n_rows);
}
和相应的输出。
---- RESULT ----
0 0 0
0 4 4
0 5 6
欢迎就此问题提供任何帮助以及评论或代码格式。
您使用 row==0
and/or col==0
调用 AverageSurroundings
(请参阅 Average
中的循环变量)。
但是 std::size_t
是 UNSIGNED 类型...所以当它为零时,负 1,它在 AverageSurroundings
的循环中下溢并且 returns 0xFFFF FFFF FFFF FFFF
...明显大于row+1
(或col+1
)。所以循环不会执行一次。
即使没有下溢,您仍然会在矩阵之外,即使使用适当的“-1”作为索引...