Page 1 of 1

[SOLVED] Spinner Increment/Decrement

Posted: Tue Nov 03, 2009 07:18
by Van
CEGUI 0.7.1 SVN Branch

Code: Select all

   mSpinnerUnits = (CEGUI::Spinner *) CEGUI::WindowManager::getSingleton().createWindow( CEGUILOOK"/Spinner", mStr );
   mSpinnerUnits->setMinimumValue( 1.0f );
   mSpinnerUnits->setStepSize( 0.01f );
   mSpinnerUnits->setTextInputMode( CEGUI::Spinner::TextInputMode::FloatingPoint );
   mSpinnerUnits->setMaximumValue( 31.0f );
   mSpinnerUnits->setCurrentValue( 31.0f );


Spinner Down Arrow: 31.00 -> 30.99
Spinner Down Arrow: 30.99 -> 30.98
Spinner Down Arrow: 30.98 -> 30.9700000001
Spinner Down Arrow: 30.9700000001 -> 30.9600000001
Spinner Down Arrow: 30.9600000001 -> 30.9500000002

Why?

Re: [BUG] Spinner Increment/Decrement

Posted: Tue Nov 03, 2009 11:27
by scriptkid
This is a hardware (cpu) limitation. Oddly, i could not come up with a link (quickly) so maybe i was searching with the wrong words.
[edit] found something: http://www.cygnus-software.com/papers/c ... floats.htm[/edit]

It all has to do with the same reason why you should never compare floating point numbers exactly, but within a margin.

Re: [BUG] Spinner Increment/Decrement

Posted: Tue Nov 03, 2009 13:10
by Van
Didn't have this problem in CEGUI 0.6.x. So what changed and why?

The floating point "error" is a from poor compiler implementation (Microsoft being one of the worst) and poor processor implementation (intel has gotten real lazy).

Re: [BUG] Spinner Increment/Decrement

Posted: Tue Nov 03, 2009 19:07
by scriptkid
Didn't have this problem in CEGUI 0.6.x. So what changed and why?


Not sure, but a long time ago (rev. 1741) the spinner had its math changed from float to double.

Maybe you are using a different compiler or otherwise different setup now?

Re: [BUG] Spinner Increment/Decrement

Posted: Thu Nov 05, 2009 00:52
by Van
Compiler: MSVS 9.0+

Bad Compiler! Bad!


Code: Select all

float getObjectTypeMinimumUnit(void)
{
  double mUnit = 1.0f;

// PROBLEM HERE
  if ( something ) mUnit  = 0.01f;
// PROBLEM HERE

  return mUnit;
}

... somewhere in code life ...
   double mUnit =  MyObject->getObjectTypeMinimumUnit();

// PROBLEM HERE
   mUnit = 0.0993156789;
// PROBLEM HERE

   mSpinnerUnits->setMinimumValue( mUnit );

... somewhere in code life ...


The fix is to remove the numerical suffix f and add a trailing zero.

Code: Select all

double getObjectTypeMinimumUnit(void)
{
  double mUnit = 1.0;
  if ( something ) mUnit = 0.010;
  return mUnit;
}