Comparing floats through math not working properly

I am trying to increment a float with a condition that id mod equals or greater than 0.5 then it should round it else it should increase the float. I get the results very unconsistantly sometimes it does but mostly it doesnt round at 0.5 but goes upto 0.6 tried variously methods not woking. screenshot is attached

It doesn't make sense to find the remainder of a decimal divided by an integer.

I am trying to seperate the 1st decimal place from the decimal which actually gives the result correct as you can see...but the if condition doesnt trigger

Also I've discovered that this problem occurs between 4-16 numbers before and after that work perfectly fine

In this case, try:

image

Decimal.aia (1.6 KB)

image

1 Like

I am able to seperate the decimals. but the condition works in a weird way. seperating is not an issue

Try increasing the number of digits of precision of the decimals using the AI2 math block for that, to uncover any rounding behind the scenes.

Also, to avoid floating point wierdness with decimal fractions, try to transforming the test into a test on double the number.

That should eliminate fractions from the test.

Don't trust Do It, it rounds values.

Behind the scenes ...

how should i solve this?

Banking programs store US money as integer pennies to avoid float errors in decimal fractions like 0.1

This is a good time to use the secret AI2 rational numbers internal data type.

Use 1/10 instead of 0.1

Use 1/2 instead of 0.5

Your procedure is the only place that variable gets updated, I hope.

Avoid the decimal point in those numbers to stay rational.

My prior post used the thought process of a mathematician.

Here is an Engineer approach.

Replace that 0.5 in the comparison with 0.499

That should account for fractional losses over thousands of 0.1 increments.

Thinking like a mathematician did not work.

But thinking like an engineer did ...


global over

1 Like

Here is a float-free approach, using just integers ...


blocks

Though I have shown 2 different ways to work around this, I have not explained the inconsistency.

Here is a possible clue ...
(from MIT App Inventor Math Blocks)

round

Returns the given number rounded to the closest integer. If the fractional part is < .5 it will be rounded down. It it is > .5 it will be rounded up. If it is exactly equal to .5, numbers with an even whole part will be rounded down, and numbers with an odd whole part will be rounded up. (This method is called round to even.)

ceiling

Returns the smallest integer that’s greater than or equal to the given number.

floor

Returns the greatest integer that’s less than or equal to the given number.

Is it possible this round technique is being applied behind the scenes?

Hmm. Further investigation is warranted I think because 0.5 is exactly representable in an IEEE 754 floating point number. It'd be one thing if it were something like 1/3 but anything that's a power of 1/2 (up to the power limit of a double floating point value) ought to be acceptable as far as App Inventor is concerned.

This is the result I got adding 1/10 to 0 and watching for 1/2 crossings.
Some of them happened at .6 while others happened at .5



blocks