C++ 数字类型介于0和1之间
是否有一种自然的方法来定义介于0和1之间的数字类型?实际上,我们可以用double做任何事情,问题是我应该在一些函数中定义一些绑定检查,我有一个(可能很愚蠢的)想法,将绑定检查外包给一个类,比如C++ 数字类型介于0和1之间,c++,C++,是否有一种自然的方法来定义介于0和1之间的数字类型?实际上,我们可以用double做任何事情,问题是我应该在一些函数中定义一些绑定检查,我有一个(可能很愚蠢的)想法,将绑定检查外包给一个类,比如 class Probability { // the value of the Probability double val; Probability(double val):value(val){ // freak out if val > 1 or val
class Probability {
// the value of the Probability
double val;
Probability(double val):value(val){
// freak out if val > 1 or val < 0
//...
//
};
// operators such as
Probability operator + (Probability const & a, Probability const & b){
double result a.val + b.val;
if ((result > 1) || (result < 0)){
// freak out
result = 0
}
return result;
}
// ...
//
}
类概率{
//概率值
双val;
概率(双val):值(val){
//如果val>1或val<0,则会出现异常
//...
//
};
//运营商,如
概率运算符+(概率常数a、概率常数b){
双结果a.val+b.val;
如果((结果>1)| |(结果<0)){
//发疯
结果=0
}
返回结果;
}
// ...
//
}
这种方法的问题可能是它会减慢每个操作。有没有更快的绑定检查方法?我还想知道如何处理上面代码中的“畸形”部分。畸形”选项很简单:throw std::invalid_argument
。投掷有点慢并不重要;反正你也得不到答案。好处是不抛出速度很快,因为优化器可以假设非异常路径的可能性更大
性能方面,最好使用IntermediateResult
类,以便只检查返回到概率的最终赋值。这避开了0.75+0.5-0.6
示例。这个“抓狂”选项很简单:抛出std::invalid_参数。投掷有点慢并不重要;反正你也得不到答案。好处是不抛出速度很快,因为优化器可以假设非异常路径的可能性更大
性能方面,最好使用IntermediateResult
类,以便只检查返回到概率的最终赋值。这避开了0.75+0.5-0.6
示例。您可以使用类概率
强制执行边界,在内部存储双精度。如果希望P(0.75)+P(0.5)-P(0.6)
等操作正常工作,可以让操作符返回一个代理对象,该对象不进行边界检查。这个代理对象将有一个到概率
的转换操作符,概率
构造函数将检查边界。如果您只直接使用Probability
类型,并允许形式为ProbabilityResultProxy
的临时变量,您将获得所需的行为
下面的示例概述了这种方法。很明显,在实际实现中,您可能会缺少很多东西,但我希望将重点放在一个特定的解决方案上,而不是提供一个完整的类
:
#包括
类概率{
公众:
概率(双值){
如果(值<0 | |值>1)抛出std::runtime_错误(“无效概率”);
价值=价值;
}
双值()常量{返回值}
私人:
双值;
};
类概率ResultProxy{
公众:
显式ProbabilityResultProxy(双p):值_Up{}
双值()常量{返回值}
算子概率(){
返回概率(值u);
}
私人:
双值;
};
ProbabilityResultProxy运算符+(常数概率和lhs、常数概率和rhs){
返回ProbabilityResultProxy(lhs.value()+rhs.value());
}
ProbabilityResultProxy运算符+(常量ProbabilityResultProxy和lhs、常量Probability和rhs){
返回ProbabilityResultProxy(lhs.value()+rhs.value());
}
ProbabilityResultProxy运算符+(常数概率和lhs、常数概率ResultProxy和rhs){
返回ProbabilityResultProxy(lhs.value()+rhs.value());
}
ProbabilityResultProxy运算符+(常量ProbabilityResultProxy和lhs、常量ProbabilityResultProxy和rhs){
返回ProbabilityResultProxy(lhs.value()+rhs.value());
}
ProbabilityResultProxy运算符-(常数概率和lhs,常数概率和rhs){
返回ProbabilityResultProxy(lhs.value()-rhs.value());
}
ProbabilityResultProxy运算符-(常量ProbabilityResultProxy和lhs,常量Probability和rhs){
返回ProbabilityResultProxy(lhs.value()-rhs.value());
}
ProbabilityResultProxy运算符-(常量概率和lhs,常量概率ResultProxy和rhs){
返回ProbabilityResultProxy(lhs.value()-rhs.value());
}
ProbabilityResultProxy运算符-(常量ProbabilityResultProxy和lhs,常量ProbabilityResultProxy和rhs){
返回ProbabilityResultProxy(lhs.value()-rhs.value());
}
int main(){
概率p1(0.75);
概率p2(0.5);
概率p3(0.6);
概率结果=p1+p2-p3;
std::cout您可以使用类Probability
来强制执行边界,在内部存储一个double。如果您需要诸如p(0.75)+p(0.5)-p(0.6)之类的操作
要工作,可以让操作符返回一个代理对象,该对象不进行边界检查。此代理对象将有一个到概率
的转换操作符,而概率
构造函数将检查边界。如果您只直接使用概率
类型,并允许f的临时值ormProbabilityResultProxy
,您将获得所需的行为
下面的示例概述了这种方法。很明显,在实际实现中,您可能会缺少很多东西,但我想专注于一个特定的解决方案,而不是提供一个完整的类
:
#包括
类概率{
公众:
概率(双值){
如果(值<0 | |值>1)抛出std::runtime_错误(“无效概率”);
价值=价值;
}
双值()常量{返回值}
私人:
双值;
};
类概率ResultProxy{
公众:
显式ProbabilityResultProxy(双p):值_Up{}
双值()常量{return v
#include <iostream>
class Probability {
public:
Probability(double value) {
if (value < 0 || value > 1) throw std::runtime_error("Invalid probability");
value_ = value;
}
double value() const { return value_; }
private:
double value_;
};
class ProbabilityResultProxy {
public:
explicit ProbabilityResultProxy(double p) : value_(p) {}
double value() const { return value_; }
operator Probability() {
return Probability(value_);
}
private:
double value_;
};
ProbabilityResultProxy operator+(const Probability& lhs, const Probability& rhs) {
return ProbabilityResultProxy(lhs.value() + rhs.value());
}
ProbabilityResultProxy operator+(const ProbabilityResultProxy& lhs, const Probability& rhs) {
return ProbabilityResultProxy(lhs.value() + rhs.value());
}
ProbabilityResultProxy operator+(const Probability& lhs, const ProbabilityResultProxy& rhs) {
return ProbabilityResultProxy(lhs.value() + rhs.value());
}
ProbabilityResultProxy operator+(const ProbabilityResultProxy& lhs, const ProbabilityResultProxy& rhs) {
return ProbabilityResultProxy(lhs.value() + rhs.value());
}
ProbabilityResultProxy operator-(const Probability& lhs, const Probability& rhs) {
return ProbabilityResultProxy(lhs.value() - rhs.value());
}
ProbabilityResultProxy operator-(const ProbabilityResultProxy& lhs, const Probability& rhs) {
return ProbabilityResultProxy(lhs.value() - rhs.value());
}
ProbabilityResultProxy operator-(const Probability& lhs, const ProbabilityResultProxy& rhs) {
return ProbabilityResultProxy(lhs.value() - rhs.value());
}
ProbabilityResultProxy operator-(const ProbabilityResultProxy& lhs, const ProbabilityResultProxy& rhs) {
return ProbabilityResultProxy(lhs.value() - rhs.value());
}
int main() {
Probability p1(0.75);
Probability p2(0.5);
Probability p3(0.6);
Probability result = p1 + p2 - p3;
std::cout << result.value() << "\n";
try {
Probability result2 = p1 + p2;
std::cout << result2.value();
} catch (const std::runtime_error& e) {
std::cout << e.what() << "\n";
}
return 0;
}