[Qt-interest] QString::number question
K. Frank
kfrank29.c at gmail.com
Wed May 26 22:10:32 CEST 2010
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.
Good luck.
K. Frank
> ...
More information about the Qt-interest-old
mailing list