[Qt-interest] QString::number question

marc at mferland.net marc at mferland.net
Thu May 27 00:50:41 CEST 2010


Quoting "K. Frank" <kfrank29.c at gmail.com>:

> Marc  -
>
> On Wed, May 26, 2010 at 2:39 PM, Marc Ferland <marc at mferland.net> wrote:
>> Hi,
>>
>> I'm currently using the QString::number() function to convert real
>> values to strings.  More precisely I'm using the functio with these
>> arguments: QString::number(num, 'g', 4);
>>
>> The result is a little surprising when the number is near 0. Here's a
>> little program that shows the problem I'm having:
>
> Given that you are "aware of the problems of converting binary numbers
> to decimal," I don't think that the result should be surprising (to you).
>
>> ...
>> int main()
>> {
>>   quint32 i;
>>   qreal step = 0.2;
>>   qreal start = -1.0;
>>
>>   for (i = 0; i < 10; ++i)
>>   {
>>      qDebug() << "QString::number(start, 'g', 4)" <<   
>> QString(QString::number(start, 'g', 4));
>>      qDebug() << "QString::number(start, 'f', 4)" <<   
>> QString(QString::number(start, 'f', 4));
>>      start += step;
>>   }
>> }
>>
>> The output is:
>> QString::number(start, 'g', 4) "-1"
>> ...
>> QString::number(start, 'f', 4) "-0.2000"
>> QString::number(start, 'g', 4) "-5.551e-17"
>
> This is correct -- you wouldn't want a different answer.  -5.5e-17 is a
> perfectly fine floating-point number, and is quite distinct from zero.
> There are plenty of applications in the floating-point world where it
> would be a serious error to represent this as zero when using the
> "g" format.
>
> (After all, by the time "start" gets into "QString::number(start, 'g', 4),"
> QString::number(...) has no idea that it came from
>
>    (-0.2000 + round-off error) + 0.2
>
> so it has no way to that it's within a context-dependent round-off
> error of zero.  For example, if "start" had come from
>
>    5551.0 / -1.0e20
>
> displaying it as zero would be 100% wrong.)
>
>> QString::number(start, 'f', 4) "-0.0000"
>
> You could quibble about this one.  You might argue that if the number
> displays as zero, then the minus sign should be suppressed.  But I
> think you would be in the minority here.
>
> I'm pretty sure that C++ does not impose a standard for floating-point
> display formats, and I'm not aware of any IEEE standard that covers
> this, but, as far as I know, the minus sign you see is pretty much a
> de facto standard.
>
>> QString::number(start, 'g', 4) "0.2"
>> ...
>> QString::number(start, 'f', 4) "0.8000"
>>
>> All the converted numbers seem ok, except for the 0 which shows as
>> "-0.000" or "-5.551e-17". Is there anyway to tell QString to just
>> round to the nearest value which makes sense (based on the precision
>> for example)?
>>
>> Am I forced to use a small epsilon to detect when the value is near
>> zero?
>
> In this case, to get what you want, yes.
>
> If this is a realistic representation of your actual use case, and this stuff
> really matters, you could consider using a decimal (as opposed native binary)
> arithmetic package.  But that would probably be more trouble than it's
> worth just for display purposes, and using an epsilon test should be fine.
>
>> Regards,
>>
>> Marc
>>
>> Note: Yes, I am aware of the problems of converting binary numbers to
>> decimal. I just think there should be a way to round based on the
>> precision provided.
>
> This is a common nuisance, and I kind of agree that some (convenient)
> standard facility should be offered to deal with it.  But deciding exactly
> how the rules should work, especially in borderline cases, is really
> pretty tricky.
>

Thanks for your answer.
Marc






More information about the Qt-interest-old mailing list