c++ - Correctly formatting the output -
my software has show end result user, data received though uart port, need format , round data.
i did write algorihtm that, feeling there has better solution.
my output can have mutiple ranges, need round , format correctly.
example:
1 of many results go ->
0.000 ohm 2.000 ohm
2.01 ohm 20.00 ohm
20.1 ohm 100.0 ohm
100 ohm 200 ohm
i made simple structure hold basic data formating
struct _range { float from; //0.000 first example float to; //2.000 int decimal; //3, decimal places need int unit; //unit format, ohm in example float div; //sometimes need divide result @ range //example, when reach 1000va need divide 1000 1kva };
i have static function called addunittoresult, 1 add unit result.
now asking me write function correctly format result string , round double ( need double later compare ).
correctly format means if result 0, should format 3 dedimal places.
i hope can me guys
edit:
this have handle round , dividing.
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(); } } } } }
let me try explain bit more:
i use struct _range set valid ranges output, when init result create mutiple struct of type range.
let have:
range1 -> 0.000 2.000 ohm range2 -> 2.01 20.00 ohm range3 -> 20.1 100.0 ohm range4 -> 101 200 ohm
when init result create array of 4 struct each containing data
range1 -> struct _range { float = 0.000 float = 2.000 int decimal =3; int unit = ohm; //unit format, ohm in example float div =1; }; range2 -> struct _range { float = 2.01 float = 20.00 int decimal =2; int unit = ohm; //unit format, ohm in example float div =1; }; range3 -> struct _range { float = 20.1 float = 100.0 int decimal =1; int unit = ohm; //unit format, ohm in example float div =1; }; range4 -> struct _range { float = 101 float = 200 int decimal =0; int unit = ohm; //unit format, ohm in example float div =1; };
now input function can 0 200, , have format text , round float acording ranges in structures.
i hope explains bit more
i think start improve code adding "format" member _range struct this:
struct _range { float from; //0.000 first example float to; //2.000 int decimal; //3, decimal places need int unit; //unit format, ohm in example float div; //sometimes need divide result @ range //example, when reach 1000va need divide 1000 1kva char * format; };
then initialize instances of range struct this:
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";
then reference format string appropriate range instance when print value. maybe this:
sprintf(pstr, prangeofvalue->format, value);
Comments
Post a Comment