我的软件必须向用户显示最终结果,通过UART端口接收数据,然后我需要格式化和舍入数据。
我确实写了algorihtm来做到这一点,但我的感觉是必须有一个更好的解决方案。
我的输出可能有多个范围,我需要进行舍入和格式化。
示例:
许多结果中有1个来自 - >
0.000欧姆至2.000欧姆
2.01欧姆至20.00欧姆
20.1欧姆至100.0欧姆
100欧姆至200欧姆
我制作了一个简单的结构来保存用于格式化的基本数据
struct _range
{
float from; //0.000 for first example
float to; //2.000
int decimal; //3, decimal places I need
int unit; //Unit to format, Ohm in my example
float div; //sometimes I need to divide the result at some range
//example, when I reach 1000VA I need to divide by 1000 to get 1kVA
};
我有一个名为AddUnitToResult的静态函数,这个函数会将单位添加到我的结果中。
现在我要求你帮我编写一个函数,将结果正确地格式化为字符串并将其舍入为double(我需要加倍才能比较它)。
正确格式意味着即使结果为0,也应将其格式化为3个最小位置。
我希望你能帮助我们
编辑:
这是我目前要处理的问题。
void ResultBox::SetResult(float res)
{
this->measureCounter++;
this->valueAVG +=res;
if (res > this->valueMax)
this->valueMax = res;
if (res < this->valueMin)
this->valueMin = res;
float tttmp;
if (this->RangeCount > 0 && this->ranges[0].decimal >= 0)
{
tttmp = Converter::cutDecimal(res,this->ranges[0].decimal);
}
int decimal = GetDecimalPlaces(res,0);
float div = GetDivision(res);
int unit = GetUnit(res);
tttmp=tttmp/div;
this->result = tttmp;
float tmpRes = res /div;
this->isValid =true;
WCHAR resText[20];
WCHAR finalText[20];
WCHAR maxText[20];
WCHAR minText[20];
char resTEXT[20];
tmpRes = res/div;;
std::ostringstream ss;
ss << std::fixed << std::setprecision(decimal) << tttmp;
std::string s = ss.str();
if (decimal > 0 && s[s.find_last_not_of('0')] == '.')
{
s.erase(s.size()-decimal+1);
}
Converter::dtoa(resTEXT,tmpRes);
switch(decimal)
{
case 0:
if (floor(tttmp) == tttmp)
{
swprintf(resText,L"%.0f",tttmp);
}else
{
swprintf(resText,L"%S",s.c_str());
}
swprintf(maxText,L"%.0f",this->GetMax());
swprintf(minText,L"%.0f",this->GetMin());
break;
case 1:
if (floor(tttmp) == tttmp)
{
swprintf(resText,L"%.1f",tttmp);
}else
{
swprintf(resText,L"%S",s.c_str());
}
swprintf(maxText,L"%.1f",this->GetMax());
swprintf(minText,L"%.1f",this->GetMin());
break;
case 2:
if (floor(tttmp) == tttmp)
{
swprintf(resText,L"%.2f",tttmp);
}else
{
swprintf(resText,L"%S",s.c_str());
}
swprintf(maxText,L"%.2f",this->GetMax());
swprintf(minText,L"%.2f",this->GetMin());
break;
case 3:
if (floor(tttmp) == tttmp)
{
swprintf(resText,L"%.3f",tttmp);
}else
{
swprintf(resText,L"%S",s.c_str());
}
swprintf(maxText,L"%.3f",this->GetMax());
swprintf(minText,L"%.3f",this->GetMin());
break;
case 4:
if (floor(tttmp) == tttmp)
{
swprintf(resText,L"%.4f",tttmp);
}else
{
swprintf(resText,L"%S",s.c_str());
}
swprintf(maxText,L"%.4f",this->GetMax());
swprintf(minText,L"%.4f",this->GetMin());
break;
case 5:
if (floor(tttmp) == tttmp)
{
swprintf(resText,L"%.5f",tttmp);
}else
{
swprintf(resText,L"%S",s.c_str());
}
swprintf(maxText,L"%.5f",this->GetMax());
swprintf(minText,L"%.5f",this->GetMin());
break;
}
//pogledamo če je majni
if (res < this->GetMin())
{
if (LowerEnabled == true)
{
wcscpy(finalText,L"<");
}
else
{
wcscpy(finalText,L"");
}
wcscat(finalText,minText);
}
else if (res > this->GetMax())
{
wcscpy(finalText,L">");
wcscat(finalText,maxText);
}
else
{
wcscpy(finalText,resText);
}
if (res == this->GetMin())
{
wcscpy(finalText,minText);
}
if (res == this->GetMax())
{
wcscpy(finalText,maxText);
}
if (this->unitBox)
{
WCHAR mm[10];
wcscpy(mm,L"");
TABSGuiProxy::MargeResultAndUnit(mm,unit);
if (mm[0] == ' ')
this->unitBox->SetText(&mm[1]);
else
this->unitBox->SetText(mm);
}
this->m_ptextBlock->SetText(finalText);
if (this->resultLimit)
{
if (unit == MEASRUEMENT_UNITS::kVA)
{
float fff = this->resultLimit->GetValue()*1000;
std::wostringstream ss1;
ss1 << std::fixed << std::setprecision(decimal) << fff;
std::wstring s1 = ss1.str();
if (decimal > 0 && s1[s1.find_last_not_of('0')] == '.')
{
s1.erase(s1.size()-decimal+1);
}
if (wcscmp(resText,s1.c_str()) == 0)
{
this->SetGoodResult();
}else
{
float mmm = fabs(_wtof(s1.c_str()) - this->resultLimit->GetValue()*1000) ;
//else if (fabs(IDelResoult - IDeltaLim) <= 0.001 || IDelResoult < IDeltaLim)
if (mmm<= 0.001 || tttmp < (_wtof(s1.c_str())))
{
this->SetGoodResult();
}
else
{
this->SetBadResult();
}
}
}
else
{
float fff = this->resultLimit->GetValue();
std::wostringstream ss1;
ss1 << std::fixed << std::setprecision(decimal) << fff;
std::wstring s1 = ss1.str();
if (decimal > 0 && s1[s1.find_last_not_of('0')] == '.')
{
s1.erase(s1.size()-decimal+1);
}
if (wcscmp(resText,s1.c_str()) == 0)
{
this->SetGoodResult();
}
else
{
float mmm = fabs(_wtof(resText) - this->resultLimit->GetValue()) ;
//else if (fabs(IDelResoult - IDeltaLim) <= 0.001 || IDelResoult < IDeltaLim)
if (mmm<= 0.001 || tttmp < (_wtof(s1.c_str())))
{
this->SetGoodResult();
}
else
{
this->SetBadResult();
}
}
}
}
}
让我试着解释一下:
我使用struct _range为输出设置有效范围, 当我初始化结果时,我创建了多种类型范围的结构。
我想说:
Range1 - &gt; 0.000至2.000欧姆 Range2 - &gt; 2.01至20.00欧姆 Range3 - &gt; 20.1至100.0欧姆 Range4 - &gt; 101到200欧姆
当我初始化我的结果时,我创建了一个包含4个结构的数组,每个结构都包含这个数据
Range1 ->
struct _range
{
float from = 0.000
float to = 2.000
int decimal =3;
int unit = Ohm; //Unit to format, Ohm in my example
float div =1;
};
Range2 ->
struct _range
{
float from = 2.01
float to = 20.00
int decimal =2;
int unit = Ohm; //Unit to format, Ohm in my example
float div =1;
};
Range3 ->
struct _range
{
float from = 20.1
float to = 100.0
int decimal =1;
int unit = Ohm; //Unit to format, Ohm in my example
float div =1;
};
Range4 ->
struct _range
{
float from = 101
float to = 200
int decimal =0;
int unit = Ohm; //Unit to format, Ohm in my example
float div =1;
};
现在我的函数输入可以是0到200,我必须格式化文本并围绕浮点数 根据结构中的范围。
我希望这可以解释一下
答案 0 :(得分:1)
我认为您可以通过在_range结构中添加“format”成员来改进此代码,如下所示:
struct _range
{
float from; //0.000 for first example
float to; //2.000
int decimal; //3, decimal places I need
int unit; //Unit to format, Ohm in my example
float div; //sometimes I need to divide the result at some range
//example, when I reach 1000VA I need to divide by 1000 to get 1kVA
char * format;
};
然后初始化范围结构的实例,如下所示:
Range1.from = 0.000;
Range1.to = 2.000;
Range1.decimal = 3;
Range1.format = "%.3f";
Range2.from = 2.01;
Range2.to = 20.00;
Range2.decimal = 2;
Range2.format = "%.2f";
然后在打印值时引用相应范围实例的格式字符串。也许是这样的:
sprintf(pstr, pRangeOfValue->format, value);
答案 1 :(得分:0)
在std :: cout:
之前,您可以在std中使用以下函数std::setprecision(5)
这样可以将数字四舍五入到小数点后5位。
答案 2 :(得分:0)
简单 - 使用sprintf。例如:
float variable = 0.0f;
const char buffer[ 7 ];
sprintf( buffer, "3.3f", variable );
// 3.3f => 3 places before dot and 3 after
// Examples:
// 0.123
// 12.200
// 123.456
答案 3 :(得分:0)
printf("3.3f",variable);
应该可以显示最多3位小数。