[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