【发布时间】:2012-08-12 23:19:21
【问题描述】:
我正在尝试用 C++ 重写一些 MatLab 代码,但我遇到了这个问题:
currentsign = sign(vector(i));
我在网上查到了这个链接:http://www.mathworks.co.uk/help/techdoc/ref/sign.html
我只是想知道 C++ 中是否有符号函数?如果没有,任何人都可以建议任何有关创建它的教程。
谢谢你:)
【问题讨论】:
我正在尝试用 C++ 重写一些 MatLab 代码,但我遇到了这个问题:
currentsign = sign(vector(i));
我在网上查到了这个链接:http://www.mathworks.co.uk/help/techdoc/ref/sign.html
我只是想知道 C++ 中是否有符号函数?如果没有,任何人都可以建议任何有关创建它的教程。
谢谢你:)
【问题讨论】:
template <typename T>
int sign (const T &val) { return (val > 0) - (val < 0); }
template <typename T>
std::vector<int> sign (const std::vector<T> &v) {
std::vector<int> r(v.size());
std::transform(v.begin(), v.end(), r.begin(), (int(*)(const T&))sign);
return r;
}
【讨论】:
建议
首先,编写一个函子函数,它接受单个元素并根据元素的值返回1、-1 或0
其次,将std::transform 与此函数/函子一起使用以获取输入容器并用所需值填充第二个容器
template <typename T>
int signum(const T& val) {
// implement signum logic
}
#include <vector>
#include <algorithm>
int main() {
std::vector<int> data = ....;
std::vector<int> signs(data.size());
std::transform(data.begin(), data.end(), signs.begin(), signum<int>);
}
【讨论】:
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <vector>
inline int get_signum(int val) {
return val < 0 ? -1
: val == 0 ? 0
: 1;
}
int main() {
std::vector<int> values;
for (int i = -5; i < 6; ++i)
values.push_back(i);
std::vector<int> signum(values.size());
std::transform(values.begin(), values.end(), signum.begin(), get_signum);
for (int i = 0; i < values.size(); ++i) {
std::cout << std::setw(2) << values[i] << ' ' << signum[i] << std::endl;
}
return 0;
}
【讨论】:
你可以在编译时使用模板专业化来完成。
您可以使用sign<n>::Positive、sign<n>::Negetive 和sign<n>::Zero 也可以使用sign<n>::Sign,即1|0|-1,与Matlab 的sign 相同。
#include <iostream>
template<int n>
struct sign{
enum{
Positive = (n > 0),
Negetive = (n < 0),
Zero = 0,
Sign = ((n > 0) ? 1 : -1)
};
};
template<>
struct sign<0>{
enum{
Positive = 0,
Negetive = 0,
Zero = 1,
Sign = 0
};
};
int main(){
std::cout << sign<0>::Positive << sign<0>::Negetive << sign<0>::Zero << sign<0>::Sign << std::endl;
std::cout << sign<1>::Positive << sign<1>::Negetive << sign<1>::Zero << sign<1>::Sign << std::endl;
std::cout << sign<-1>::Positive << sign<-1>::Negetive << sign<-1>::Zero << sign<-1>::Sign << std::endl;
return 0;
}
你以前在那里做sign(n),现在你会在这里做sign<n>::Sign。
【讨论】:
C99 有signbit() 和copysign(),它们似乎在Linux 上的glibc 中实现。不过,您没有指定您使用的平台,所以我不确定这是否有帮助...
【讨论】: