Can't increment a variable

Hello. Using a Xojo on a Mac in demo mode. Found what seems to be a bug while building an app. So I made the simplest app to double-check.

I added a button and a label on a window.
I added a property which I called “VariableA”, set it as double with a default value of 0.1

I added an Action to Button1:
VariableA = floor(VariableA*10)/10 + 0.1
label1.value = VariableA.ToString

Each time I push the button the value increment by 0.1 but once it reaches 0.8, it stops there. It won’t reach pass 0.8.

Can someone try it and let me know if its a bug, or a limitation of the demo mode.

Thanks,

there is no limit in what you call ‘Demo’ mode, the download is FULLY functional, you just can not make and executable file to share.

what are you trying to achieve with the code you posted?

I don’t recognize the syntax so it must be API2, are you using 19R3.1?

Mark

[quote=494727:@Serge Beaudet]Hello. Using a Xojo on a Mac in demo mode. Found what seems to be a bug while building an app. So I made the simplest app to double-check.

I added a button and a label on a window.
I added a property which I called “VariableA”, set it as double with a default value of 0.1

I added an Action to Button1:
VariableA = floor(VariableA*10)/10 + 0.1
label1.value = VariableA.ToString

Each time I push the button the value increment by 0.1 but once it reaches 0.8, it stops there. It won’t reach pass 0.8.

Can someone try it and let me know if its a bug, or a limitation of the demo mode.

Thanks,[/quote]

Its because doubles/floating-point numbers are not absolute, at some point the slight inaccuracies in the calculation add up and you get “0.7999999999999999” which when x10 and floored equals 7. I think we need to know more about what you are actually trying to do before giving a proper recommendation but you may want to use Round() or an integer.

Set a breakpoint in the debugger and step through to see how it arrives at that value and won’t go past 0.8.

if you alter your code to

If VariableA > .7 Then 
  Break
End If

Var tmp1 As Double = Floor(VariableA*10)
Var tmp2 As Double = Floor(VariableA*10)/10 
Var tmp3 As Double = Floor(VariableA*10)/10 + 0.1

VariableA = Floor(VariableA*10)/10 + 0.1
label1.value = VariableA.ToString

you can see what Alex is referring to by stepping through the code and seeing the results in the debugger

[quote=494731:@Norman Palardy]if you alter your code to

If VariableA > .7 Then 
  Break
End If

Var tmp1 As Double = Floor(VariableA*10)
Var tmp2 As Double = Floor(VariableA*10)/10 
Var tmp3 As Double = Floor(VariableA*10)/10 + 0.1

VariableA = Floor(VariableA*10)/10 + 0.1
label1.value = VariableA.ToString

you can see what Alex is referring to by stepping through the code and seeing the results in the debugger[/quote]

Yes, I had just changed my comment to say exactly that, the debugger can be the best way to see how you arrived as a certain outcome, especially if it’s repeatable.

Had you considered

if VariableA + 0.1 <= 0.9 then VariableA = VariableA + 0.1

or you need to round to two decimal places

VariableA = Floor(VariableA * 100.0) / 100.0 + 0.1

The exemple I posted is just to show that something is not working. I just made a quick simple app, which doesn’t make sense in fact, for the purpose of debugging.

But on my real app, VariableA may begin as 0.1243 or something similar, and I need a function to remove the decimal value. Maybe floor() isn’t what I need. In C, the function would be trunk(). Is there something similar in Xojo?

Now, based on Alex comment, I tried this instead:

VariableA = floor(VariableA100)/100
VariableA = floor(VariableA
10)/10 + 0.1
label1.value = VariableA.ToString

And it works… for this exemple only.

In my app I also have to perform the same operation but with 2 decimals…

Variable A = 0.02
VariableA = floor(VariableA*10)/10 + 0.01
label1.value = VariableA.ToString

I also tried:

VariableA = floor(VariableA1000)/1000
VariableA = floor(VariableA
100)/100 + 0.01
label1.value = VariableA.ToString

But this time it doesn’t work. It gets stuck at 0.07.

If someone could try it. it is just two components and a couple of lines of code.
if it is not a bug, there might be ways to improve it.

Var noDecimal As Integer = MyDouble
break
system.debuglog noDecimal.toString(Nil, "#")

If you are going to use 4 decimals or less, you may want to try Currency instead of Double.

because double ToString will show you a rounded value
if you see 7 then it is 6,9999999999999991 … Alex already mentioned that
you can see the real value in the debug window.
the problem is Floor it round down

how about

VariableA = Round(VariableA * 10.0) / 10.0 + 0.1

100 = integer
100.0 = double

can one of the forums admins move this into the general channel
@Greg O’Lone ?

If I put it here it is because I believe it is a bug of some sort… I might be wrong.

This works:

VariableA = floor(VariableA100)/100
VariableA = floor(VariableA
10)/10 + 0.1
label1.value = VariableA.ToString

and this doesn’t work:

VariableA = floor(VariableA1000)/1000
VariableA = floor(VariableA
100)/100 + 0.01
label1.value = VariableA.ToString

What I am trying to do is the following:

The variableA is populated by another process and can contain any values from 0.01 and 1. ex: 0.023434, 0.14323
When it is lower than 0.1, I want to be able to round it up to the first two decimals and add 0.01.
When it is higher or equal to 0.1 I want to be able to round it up to the first decimal and add 0.1
So It looks like this: …0.06, 0.07, 0.08, 0.09, 1., 1.1, 1.2, 1.3…

Ex: Variable A = 0.0789
When I increment by 0.01 I want it to be 0.08
or Variable A = 0.884
When I increment by 0.1 I want it to be 0.9

and because of this data type it is 0.0799999999999999
and you floor would make 7 not 8
had you tried Currency as mentioned?

floating point values are inherently inaccurate
since its all the sums of powers of 2 you can get some that are “close” but not quite
and then your code has to try & compensate for that inaccuracy

or, you say to hell with using doubles at all and convert everything when you read it in and put it into an integer that is appropriately scaled and on display scale it the other way and only lose precision at the boundaries where you read the data oor display it

The problem is your use of Floor(). Use Round() instead.

round might just give different problems since rounding .789 will give .8 and then he adds .1 and it appears to jump .8 to .9

[quote=494854:@Serge Beaudet]If I put it here it is because I believe it is a bug of some sort… I might be wrong.

This works:

VariableA = floor(VariableA100)/100
VariableA = floor(VariableA
10)/10 + 0.1
label1.value = VariableA.ToString

and this doesn’t work:

VariableA = floor(VariableA1000)/1000
VariableA = floor(VariableA
100)/100 + 0.01
label1.value = VariableA.ToString

What I am trying to do is the following:

The variableA is populated by another process and can contain any values from 0.01 and 1. ex: 0.023434, 0.14323
When it is lower than 0.1, I want to be able to round it up to the first two decimals and add 0.01.
When it is higher or equal to 0.1 I want to be able to round it up to the first decimal and add 0.1
So It looks like this: …0.06, 0.07, 0.08, 0.09, 1., 1.1, 1.2, 1.3…

Ex: Variable A = 0.0789
When I increment by 0.01 I want it to be 0.08
or Variable A = 0.884
When I increment by 0.1 I want it to be 0.9[/quote]

As said above by others, you use Floor (down). You might want to use Ceil (up) instead.
you want a value of 0.1 or lower (0.05?) to be rounded to (0.1) and then add 0.1 ?

Var d As Double = Ceil(1.234 * 10) / 10

break // Check debugger value

d = d + 0.1

break // Check debugger value again.

It works perfectly fine when I set the variable as a currency instead of a double.

Thanks Alberto, I should have tried your solution first.
Thanks Marcus, and thanks all the others.

I still think there is something wrong with this floor() function though.
Why would floor(8.xxx) be 7.9999999…

Thanks again,

[quote=494876:@Serge Beaudet]I still think there is something wrong with this floor() function though.
Why would floor(8.xxx) be 7.9999999…[/quote]
You do understand about floating point numbers, don’t you?

If your increment is 0.01, I don’t know why you didn’y just scale to 0…100 and use integers.