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