Force Input Control Rounding on SetVariables
jjweimer
I have this recent thread about increments on SetVariable controls.
I would like to have a simpler way to implement rounding of values on SetVariables. I propose an additional checkbox as shown in the attached image.
My expectation would be bug reports of values that weren't quite what people thought they should get. We get bug reports on arithmetic in a steady trickle.
With this control panel:
PauseUpdate; Silent 1 // building window...
NewPanel /W=(150,50,450,250)
SetVariable setvar0,pos={53.00,71.00},size={140.00,14.00},bodyWidth=60,proc=SetVarProc,title="rounded number:"
SetVariable setvar0,format="%3.1f",limits={-2,2,0.1},value= _NUM:2,live= 1
EndMacro
This action proc does what you want:
STRUCT WMSetVariableAction &sva
switch( sva.eventCode )
case 1: // mouse up
case 2: // Enter key
case 3: // Live update
Variable rvalue
sscanf sva.sval, "%f", rvalue
printf "dval = %.17g; sval = %s; rvalue = %.17g\r", sva.dval, sva.sval, rvalue
SetVariable $(sva.ctrlname), win=$(sva.win), value=_NUM:rvalue
break
case -1: // control being killed
break
endswitch
return 0
End
You still don't get exact values, of course. This "rounding" results in slightly different values than simply incrementing by the digital equivalent of 0.1, so the results in some cases change the greater-than and less-than relationships to the intended exact decimal number:
So to summarize, I think trying to round would result in unexpected results just as much as not rounding. You can implement your own rounding, and get a result that you can inspect in detail rather than burying it in our source code. And you can adjust your rounding to get the results you need.
September 25, 2018 at 12:39 pm - Permalink
Why can't you just do it in the gui control procedure?
September 25, 2018 at 02:06 pm - Permalink
Fair enough.
This does force one to think explicitly about what is displayed in the panel versus what is actually stored/read for use.
But wait! You have sva.sval! That is in the format of the panel. Ok, this may do it.
In any case, I see that I may need to refresh the setvariable to force the increment to be exactly what I want rather than the rounding at zero problem going from ± 0.1 -> 0).
Thanks!
September 25, 2018 at 02:13 pm - Permalink
Yes, you can set the SetVariable value from within the action proc when the event is one of the "value changed" events. I recently had to fix that so I know it works now :)
September 26, 2018 at 11:09 am - Permalink
So, let me try to summarize all this. Consider the case where you want a setvariable control to increment from -2 to 2 in 0.1 steps. You want the steps to be EXACTLY 0.1.
You have two ways to make this happen within a SetVariableControl structure function
Method I - Read sval
Method II - Read dval
Of the two methods, the first seems the easiest.
When you wish to read the panel value using ControlInfo, you are out of luck with Method I. The ONLY way to force the value from ControlInfo on a setvariable is to use the approach below where MyRoundedValue is a function to force the value to a given precision.
value = MyRoundedValue(v_value,precision)
SetVariable setvariablename value=_NUM:value
My request was to have a checkbox to make the rounding happen behind the scenes so that ControlInfo would automatically format v_value as it was read by ControlInfo.
In this regard, I might amend my feature request to this ...
---
I would like to have ControlInfo on a SetVariable also return a value V_FValue where V_FValue (or a more appropriate name) is the value formatted according to the format string provided in the settings. When the format string is empty, V_FValue is the same as V_Value.
---
September 26, 2018 at 05:22 pm - Permalink
Please note that method 1 doesn't result in an exact number either, unless you use the string notation in arithmetic (which is going to be really difficult, though not impossible). The conversion to floating-point has its own floating-point error. The simple fact is that 0.1 when represented as a sum of powers of 1/2 is an infinitely repeating fraction.
September 26, 2018 at 06:23 pm - Permalink
Oh! OK. I'm clearly not as clear on this as I thought.
Truthfully, now that I've had a week to go through this, I realize that my main issue is solved. I want to avoid the rounding errors in the DISPLAY of the number. Rather than showing 2.7x10^{-17}, I wanted 0.0. I fixed that by setting the format of the display number.
Otherwise, for internal calculations, I should also have realized that what I am asking is ... silly. For all the time I spend telling my students to think about the RELATIVE influence (uncertainty) of a factor, you would think it would have dawned on me that we are talking about a round off error that affects the actual value in a relative manner by ppm or less.
I respectfully withdraw my request.
Thanks for the patience to follow me down a rabbit hole and drag me back out. :-)
September 27, 2018 at 05:35 am - Permalink
The whole business of floating-point truncation error can be really hard to wrap your head around. There are places in Igor's code where we go to great lengths to work around it in a sane way. Think about the edge values of histogram bins. What happens with a data value that is "equal" to a histogram bin edge where the bins are increments of (very nearly) 0.1...
September 27, 2018 at 09:42 am - Permalink