📄 vars.cpp
字号:
if (vi != valuesTree.end())
valu = TValue(vi->second);
else if (!str2special(valname, valu))
raiseError("attribute '%s' does not have value '%s'", name.c_str(), valname.c_str());
}
else {
TStringList::const_iterator vi = find(values->begin(), values->end(), valname);
if (vi!=values->end())
valu = TValue(int(vi - values->begin()));
else if (!str2special(valname, valu))
raiseError("attribute '%s' does not have value '%s'", name.c_str(), valname.c_str());
}
}
bool TEnumVariable::str2val_try(const string &valname, TValue &valu)
{
if (values->size() > 50) {
if (valuesTree.empty())
createValuesTree();
map<string, int>::const_iterator vi = valuesTree.find(valname);
if (vi != valuesTree.end()) {
valu = TValue(vi->second);
return true;
}
return str2special(valname, valu);
}
else {
TStringList::const_iterator vi = find(values->begin(), values->end(), valname);
if (vi!=values->end()) {
valu = TValue(int(vi - values->begin()));
return true;
}
return str2special(valname, valu);
}
}
// Converts TValue into a string representation of value. If invalid, string 'ERR' is returned.
void TEnumVariable::val2str(const TValue &val, string &str) const
{ if (val.isSpecial()) {
special2str(val, str);
return;
}
if (val.svalV) {
const TDiscDistribution *dval = dynamic_cast<const TDiscDistribution *>(val.svalV.getUnwrappedPtr());
if (!dval)
raiseError("invalid value type");
str = "(";
char buf[12];
const_PITERATE(TDiscDistribution, di, dval) {
if (di != dval->begin())
str+=", ";
sprintf(buf, "%1.3f", *di);
str += buf;
}
str += ")";
}
str = val.intV<int(values->size()) ? values->operator[](val.intV) : "#RNGE";
}
void TEnumVariable::createValuesTree()
{
int i = 0;
const_PITERATE(TStringList, vi, values)
valuesTree[*vi] = i++;
}
TIntVariable::TIntVariable()
: TVariable(TValue::INTVAR, true),
startValue(0),
endValue(-1)
{}
TIntVariable::TIntVariable(const string &aname)
: TVariable(aname, TValue::INTVAR, true),
startValue(0),
endValue(-1)
{}
#define CHECK_INTERVAL if (startValue>endValue) raiseError("interval not given");
bool TIntVariable::firstValue(TValue &val) const
{ CHECK_INTERVAL
return ((val = TValue(startValue)).intV<endValue);
}
bool TIntVariable::nextValue(TValue &val) const
{ CHECK_INTERVAL
return (++val.intV<=endValue);
}
TValue TIntVariable::randomValue(const int &rand)
{ CHECK_INTERVAL
if (!randomGenerator)
randomGenerator = mlnew TRandomGenerator();
return TValue(rand<0 ? randomGenerator->randint(startValue, endValue) : (rand % (endValue-startValue+1) + startValue));
}
int TIntVariable::noOfValues() const
{ return startValue<=endValue ? endValue-startValue+1 : -1; }
void TIntVariable::str2val(const string &valname, TValue &valu)
{ if (str2special(valname, valu))
return ;
int i;
if (!sscanf(valname.c_str(), "%i", &i))
raiseError("invalid argument (integer expected)");
if ((startValue<=endValue) && ((i<startValue) || (i>endValue)))
raiseError("value %i is out of range %i-%i", i, startValue, endValue);
valu = TValue(i);
}
bool TIntVariable::str2val_try(const string &valname, TValue &valu)
{ if (str2special(valname, valu))
return true;
int i;
if (!sscanf(valname.c_str(), "%i", &i) || ((startValue<=endValue) && ((i<startValue) || (i>endValue))))
return false;
valu = TValue(i);
return true;
}
void TIntVariable::val2str(const TValue &valu, string &vname) const
{ if (valu.isSpecial())
special2str(valu, vname);
else {
char buf[10];
sprintf(buf, "%i", valu.intV);
vname=buf;
}
}
TFloatVariable::TFloatVariable()
: TVariable(TValue::FLOATVAR, true),
startValue(-1.0),
endValue(0.0),
stepValue(-1.0),
numberOfDecimals(3),
scientificFormat(false),
adjustDecimals(2)
{}
TFloatVariable::TFloatVariable(const string &aname)
: TVariable(aname, TValue::FLOATVAR, true),
startValue(-1.0),
endValue(0.0),
stepValue(-1.0),
numberOfDecimals(3),
scientificFormat(false),
adjustDecimals(2)
{}
bool TFloatVariable::firstValue(TValue &val) const
{ if ((stepValue<=0) || (startValue<endValue))
return false;
val = TValue(startValue);
return true;
}
bool TFloatVariable::nextValue(TValue &val) const
{ if (stepValue<=0)
return false;
return ((val.floatV+=stepValue)<=endValue);
}
TValue TFloatVariable::randomValue(const int &rand)
{ if ((stepValue<=0) || (startValue>=endValue))
raiseError("randomValue: interval not given");
if (!randomGenerator)
randomGenerator = mlnew TRandomGenerator();
if (rand<0)
return TValue(randomGenerator->randfloat(startValue, endValue));
else
return TValue(float(double(rand)/double(4294967295.0)*(endValue-startValue)+startValue));
}
int TFloatVariable::noOfValues() const
{ return stepValue>0 ? int((endValue-startValue)/stepValue) : -1; }
inline int getNumberOfDecimals(const char *vals, bool &hasE)
{
const char *valsi;
for(valsi = vals; *valsi && ((*valsi<'0') || (*valsi>'9')); valsi++);
if (!*valsi)
return -1;
if ((*valsi=='e') || (*valsi=='E')) {
hasE = true;
return 0;
}
for(; *valsi && (*valsi!='.'); valsi++);
if (!*valsi)
return 0;
int decimals = 0;
for(valsi++; *valsi && (*valsi>='0') && (*valsi<='9'); valsi++, decimals++);
hasE = hasE || (*valsi == 'e') || (*valsi == 'E');
return decimals;
}
int TFloatVariable::str2val_low(const string &valname, TValue &valu)
{
if (str2special(valname, valu))
return 1;
const char *vals;
char *tmp = NULL;
int cp = valname.find(',');
if (cp!=string::npos) {
vals = tmp = strcpy(new char[valname.size()+1], valname.c_str());
tmp[cp] = '.';
}
else
vals = valname.c_str();
float f;
int ssr = sscanf(vals, "%f", &f);
int res;
if (!ssr || (ssr==EOF)) {
res = -1;
}
else {
valu = TValue(f);
if (((startValue<=endValue) && (stepValue>0) && ((f<startValue) || (f>endValue)))) {
res = -2;
}
else {
res = 1;
valu = TValue(f);
int decimals;
switch (adjustDecimals) {
case 2:
numberOfDecimals = getNumberOfDecimals(vals, scientificFormat);
adjustDecimals = 1;
break;
case 1:
decimals = getNumberOfDecimals(vals, scientificFormat);
if (decimals > numberOfDecimals)
numberOfDecimals = decimals;
}
}
}
if (tmp)
delete tmp;
return res;
}
void TFloatVariable::str2val(const string &valname, TValue &valu)
{
switch (str2val_low(valname, valu)) {
case -1: raiseError("'%s' is not a legal value for continuous attribute '%s'", valname.c_str(), name.c_str());
case -2: raiseError("value %5.3f out of range %5.3f-%5.3f", valu.floatV, startValue, endValue);
}
}
bool TFloatVariable::str2val_try(const string &valname, TValue &valu)
{
return str2val_low(valname, valu) == 1;
}
void TFloatVariable::val2str(const TValue &valu, string &vname) const
{ if (valu.isSpecial())
special2str(valu, vname);
else {
char buf[64];
const float f = fabs(valu.floatV);
if (scientificFormat)
sprintf(buf, "%g", valu.floatV);
else
sprintf(buf, "%.*f", numberOfDecimals, valu.floatV);
vname = buf;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -