<Swing Dev> [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue

Pankaj Bansal pankaj.b.bansal at oracle.com
Tue Mar 10 12:34:30 UTC 2020


Hello Sergey/Vlad/Alexey,

Sorry, I could not reply to this earlier. I have one doubt about this 
approach. Won't the calculation of stepCount itself suffer from floating 
point issue? I mean the user will pass min, max, stepsize, then wont the 
calculation of steps required to go from min to max will also suffer 
from same floating point issue? I think there can be an rounding of 
error of -1 or +1 in calculation of step count.

eg.

int steps =0;

for (double i=min+stepsize; i<=max; i+=stepsize)
	steps++;

double min=-.15,max=0.15,stepsize=.05, the steps is calculated as 5. double min=-.15,max=0.20,stepsize=.05, the steps is calculated as 7 instead of 6.


The reason is that, there is floating point error in first case, but it is not present in second case.

I think the best we can do here is as Sergey suggested in his first reply to use Math.fma to reduce the floating point error chances from 2 to 1 or just close this as not an issue

Regards,

Pankaj


On 19/02/20 3:49 AM, Sergey Bylokhov wrote:
> I think it should work, the step will counts from the default value.
>
> So currently:
> 1. if the user set default value to X1 and then he iterates forward 
> 100 times then he will get some X2. During this calculation, he could 
> get "100" rounding issues.
> 2. If later the user decides iterates backward then most probably he 
> will not get X1, and the amount of possible "rounding issues" will be 
> 200.
>
> If the user will repeat steps 1. and 2. then each time the values will 
> "float".
>
> If we will use counter then in the worst case we will get only two 
> roundings per step: X1+step*100 = X2(if we will use fma we will get 
> only one for every step).
>
> It will not solve all issues but at least will make the iteration 
> "stable".
>
> On 2/17/20 1:59 am, Alexey Ivanov wrote:
>> Hi Vlad,
>>
>> The idea looks reasonable. However, it does not allow for manual 
>> editing. The cases where max and min values are not multiples of step 
>> would be hard to handle with this approach. For example: max = 10.05, 
>> min = 0.01, step = 0.1; how many ticks are there? What if the user 
>> enters 1.01015; the value should change to 1.11015 or 0.91015.
>>
>> On 13/02/2020 22:22, Volodin, Vladislav wrote:
>>> Hello Sergey, Alexey and Pankaj,
>>>
>>> I am reading the current discussion and I was thinking about an idea 
>>> changing the code in the way that instead of working with 
>>> float/double numbers we work with integer ticks. For example, the 
>>> model remembers the min/max/step values and calculates a number of 
>>> steps required to reach from min to max. All increment/decrement 
>>> actions are done against the current ˋtickˋ value. If the current 
>>> ˋtickˋ reaches 0 - we return min; if maxTick — we return max. And 
>>> the current value can be always counted as (min + tick * step) if 
>>> tick is neither zero, nor max tick count.
>>>
>>> At least if we deal with integer ticks, but all reading operations 
>>> calculate on the fly, we will be able to control the 
>>> representativeness of output.
>>>
>>> As always, I don’t know all the details and possible consequences, 
>>> so feel free to ignore my email, if I am wrong.
>>>
>>> Kind regards,
>>> Vlad
>>>
>>> Sent from myPad
>>>
>>>> On 13. Feb 2020, at 22:34, Sergey Bylokhov 
>>>> <Sergey.Bylokhov at oracle.com> wrote:
>>>>
>>>> On 2/12/20 8:21 am, Alexey Ivanov wrote:
>>>>> The bug report says that going from -0.15 to -0.10 does not allow 
>>>>> going back to -0.15. This happens because the result of this 
>>>>> sequence of operations cannot be represented exactly, or, in other 
>>>>> words, because of rounding errors; or rather the result is less 
>>>>> than the set minimal value.
>>>>> Can we set the value of the spinner to the set minimal value 
>>>>> instead of disallowing the operation. I mean, after going up the 
>>>>> displayed value is -0.10; going down by 0.05 gives the result 
>>>>> which is less than the minimal value for the spinner, and thus 
>>>>> going down is not allowed. What if we set the value of the spinner 
>>>>> to its minimal value instead?
>>>> In this case, we will need to update all types including int. Isn't 
>>>> it will be surprised that the spinner will show the value which is 
>>>> not calculated as
>>>> "defaultValue + stepValue * stepCount"?
>>>>
>>>>
>>>> -- 
>>>> Best regards, Sergey.
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/swing-dev/attachments/20200310/663158c4/attachment.htm>


More information about the swing-dev mailing list