c++ - Qt qreal calculates wrong -
i want edit opacity qgraphicsitem
qspinbox
. qspinbox
gives me value 57 use set opacity of item. changed opacity item , want fill qspinbox
. setting value of box results in mistake.
qdebug() << (int)(qreal)(0.57 * 100.0);
outputs 56
is known bug? there workaround?
integers fit in mantissa have exact representation in floating point, static_cast<qreal>(100.0) == 100
holds , represented 100*2^0
.
rationals denominators of form 2^-n
have exact representation in floating point long numerator fits in mantissa, e.g. static_cast<qreal>(0.25*4) == 1
holds long compiler doesn't use brain-dead decimal-to-floating-point conversion function. when compilers parse code, convert both 0.25
, 4
floating point representation, , perform multiplication obtain value of constant expression.
but static_cast<qreal>(0.57)
has no representation m*2^-n
, sufficiently small integer m,n
, , represented inexactly. can represented bit less or more 0.57
. when multiply 100
, can less 57
- in case.
the simplest fix avoid roundtrip: store opacity everywhere integer, , convert integer floating point when changing value. in other words, ever use setopacity()
method, , never use opacity()
method. store integer-valued opacity using item's data attribute:
void setopacity(qgraphicsitem * item, int opacity) { item->setdata(kopacity, opacity); item->setopacity(opacity / 100.0); } void getopacity(qgraphicsitem * item) { auto data = item->data(kopacity); if (! data.isnull()) return data.toint(); int opacity = round(item->opacity() * 100.0); setopacity(item, opacity); return opacity; }
Comments
Post a Comment