wxSpinCtrlDouble not wrapping correctly?

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
mael15
Super wx Problem Solver
Super wx Problem Solver
Posts: 430
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

wxSpinCtrlDouble not wrapping correctly?

Post by mael15 » Mon Jun 29, 2020 11:03 am

Hi,
I have this simple wxSpinCtrlDouble:

Code: Select all

wxSpinCtrlDouble* rotSpin = new wxSpinCtrlDouble(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(80, -1), wxSP_WRAP, 0.0, 359.9, 0, 0.1);
rotSpin->SetDigits(1);
When wrapping downwards using the arrow buttons on wxMSW: 0.2, 0.1, 0.0. 359.9, 359.8 everything is fine, but upwards it jumps from 359.8 to 0.0.
Can I get rid of it?

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 4160
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxSpinCtrlDouble not wrapping correctly?

Post by ONEEYEMAN » Mon Jun 29, 2020 3:37 pm

Hi,
What do you expect it to do?

Thank you.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2429
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxSpinCtrlDouble not wrapping correctly?

Post by PB » Mon Jun 29, 2020 5:25 pm

I can confirm the issue and the reason being what I thought: computer floating point inaccuracy.

And since a picture is worth a thousand words, please observe the actual representations of value (set to be 359.9) and m_max (set to be 359.9 as well), resulting in from the user point of view an unexpected result of value > m_max test
spinctrldouble-issue.png
spinctrldouble-issue.png (24.89 KiB) Viewed 135 times
Perhaps the code should operate with all values (value, limits, increment) rounded to the number of digits set for that wxSpinCtrlDouble. Or, perhaps better yet, use an epsilon when comparing floating point numbers, but that may not be that simple either...

mael15
Super wx Problem Solver
Super wx Problem Solver
Posts: 430
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: wxSpinCtrlDouble not wrapping correctly?

Post by mael15 » Fri Jul 03, 2020 12:17 pm

thank you! so I guess there is no easy fix?

User avatar
doublemax
Moderator
Moderator
Posts: 14881
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxSpinCtrlDouble not wrapping correctly?

Post by doublemax » Fri Jul 03, 2020 1:58 pm

What happens when you set the max to 359.91 (or something similar)?
Use the source, Luke!

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2429
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxSpinCtrlDouble not wrapping correctly?

Post by PB » Fri Jul 03, 2020 2:18 pm

I do not think there generally is anything you as user can do here. I think wxFloatingPointValidator::IsInRange() may suffer from the same issue. Floating point comparisons are tricky.

I do not understand math but FWIW I wrote a function which compares two doubles for use in GUI, using the user provided number of decimal places:

Code: Select all

// This function tries to work around issues caused by floating point numbers
// representations when comparing them.
// Returns -1 when d1 < d2, 1 when d1 > 2, and 0 when d1 == d2.
int wxCompareDoublesForUI(const double d1, const double d2, wxUint8 decimalPlaces)
{
    wxCHECK_MSG(decimalPlaces <= 9, 0, "decimalPlaces must be between 0 and 9");

    // First compare only the integer parts of the values
    const wxInt64 d1IntPart = trunc(d1);
    const wxInt64 d2IntPart = trunc(d2);

    if ( d1IntPart < d2IntPart )
        return -1;
    if ( d1IntPart > d2IntPart )
        return 1;
    if ( decimalPlaces == 0 )
        return 0;

    // If the integer parts were the same, compare only the fractional parts
    // as if they were integers * 10^decimalPlaces
    const double factor = pow(10, decimalPlaces);
    const int d1FractPartAsInt = round((d1 - d1IntPart) * factor);
    const int d2FractPartAsInt = round((d2 - d2IntPart) * factor);

    return d1FractPartAsInt - d2FractPartAsInt;
}
But it is very likely a very wrong approach and smart people must have already invented the correct solution to this problem (and probably also much more efficient)...

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 4160
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxSpinCtrlDouble not wrapping correctly?

Post by ONEEYEMAN » Fri Jul 03, 2020 2:34 pm

Hi,
You can try to send an E-mail to wx-users ML to see if someone from the wx core team can suggest a possible solution.
Or maybe they can confirm that it is a bug in the library.

This is a user-oriented forum - they are not coming here, unless requested.

Thank you.

Post Reply