Momergil
Momergil

Reputation: 2281

How to show a floating number with a fixed amount of digits in Qt?

I want to display a floating number in Qt with a fixed amount of digits (4), but without filling non-used digits with zero (the equivalent of having a maximum number of digits). In other words, this is what I want to show for the following examples:

etc.. I tried many combinations of both QString::number() as well as QString::args(), without success. So how can I do that?

Note: I'm aware that for numbers higher then 1000, I'll have to apply a division and add the label 'k' manually - I'm already doing that.

EDIT: The following code does exactly what I want, only that it is quite inappropriate with all those if else. I would like to know how can I do that with Qt's functions:

float temp = getSomeValue();
const char* itemUnities[] = { "V", "W", "A", "J" };

if (temp < 10.0f)
{
    painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',3));
    painter.drawText(defaultX + 110,yPosition,tr(itemUnities[aaa]));
}
else if (temp < 100.0f)
{
    painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',2));
    painter.drawText(defaultX + 110,yPosition,tr(itemUnities[aaa]));
}
else if (temp < 1000.0f)
{
    painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',1));
    painter.drawText(defaultX + 110,yPosition,tr(itemUnities[aaa]));
}
else if (temp < 10000.0f)
{
    temp *= 0.001;

    painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',3));
    painter.drawText(defaultX + 110,yPosition,tr("k") + tr(itemUnities[aaa]));
}
else if (temp < 100000.0f)
{
    temp *= 0.001;

    painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',2));
    painter.drawText(defaultX + 110,yPosition,tr("k") + tr(itemUnities[aaa]));
}
else if (temp < 1000000.0f)
{
    temp *= 0.001;

    painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',1));
    painter.drawText(defaultX + 110,yPosition,tr("k") + tr(itemUnities[aaa]));
}
else if (temp < 10000000.0f)
{
    temp *= 0.000001;

    painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',3));
    painter.drawText(defaultX + 110,yPosition,tr("M") + tr(itemUnities[aaa]));
}
else if (temp < 100000000.0f)
{
    temp *= 0.000001;

    painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',2));
    painter.drawText(defaultX + 110,yPosition,tr("M") + tr(itemUnities[aaa]));
}
else if (temp < 1000000000.0f)
{
    temp *= 0.000001;

    painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',1));
    painter.drawText(defaultX + 110,yPosition,tr("M") + tr(itemUnities[aaa]));
}

Upvotes: 0

Views: 850

Answers (1)

Gombat
Gombat

Reputation: 2084

Since you have very specific wishes for the conversion, a built in method does not provide all the functionality, but with some tricks, you can use QString::number() and QString::truncate():

QString doubleToQStr(const double val, const size_t d)
{
  QString str = QString::number(val,'g',15);

  if( val >= std::pow(10.0,static_cast<double>(d-1)) ) 
  { 
    str.truncate(d); 

    // find magnitude
    size_t mag = 0;
    while( val >= std::pow( 10.0, static_cast<double>(mag) ) ) { mag++; } 

    if ( mag > 3 )
    {
      size_t dotpos = mag % 3;
      str.insert(dotpos,".");

      size_t mag3 = mag - dotpos;

      switch( mag3 )
      { 
      case 3:
        str += " k"; break;
      case 6:
        str += " M"; break;
      case 9:
        str += " G"; break;
      case 12:
        str += " T"; break;
      default:
        str += " ?"; break;
      }
    }
  }
  else if ( val < std::pow(10.0,static_cast<double>(-(static_cast<int>(d)-1))) )
  { str = "0.0"; }
  else
  { str.truncate(d+1); }  

  return str;
}

Here are the test cases I used:

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);

  std::cout << "99919999.9 -> " << doubleToQStr(99919999.9, 4).toStdString() << std::endl;
  std::cout << "9999.9 -> " << doubleToQStr(9999.9, 4).toStdString() << std::endl;
  std::cout << "999.9 -> " << doubleToQStr(999.9, 4).toStdString() << std::endl;
  std::cout << "99.9 -> " << doubleToQStr(99.9, 4).toStdString() << std::endl;
  std::cout << "9.9 -> " << doubleToQStr(9.9, 4).toStdString() << std::endl;
  std::cout << "0.9 -> " << doubleToQStr(0.9, 4).toStdString() << std::endl;
  std::cout << "0.09 -> " << doubleToQStr(0.09, 4).toStdString() << std::endl;
  std::cout << "0.009 -> " << doubleToQStr(0.009, 4).toStdString() << std::endl;
  std::cout << "0.0009 -> " << doubleToQStr(0.0009, 4).toStdString() << std::endl;
  std::cout << "0.00009 -> " << doubleToQStr(0.00009, 4).toStdString() << std::endl;

    return a.exec();
}

Upvotes: 2

Related Questions