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

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -