How to eliminate floating point errors

Godot Version

godot 4

Question

WTF? that’s not true, that must be 2;

that even happens with:
var x = sqrt(2)**2 == 2
print(x) #false

PLEASE, HELP ME;

I need to solve this, no matter if is just 0.1 + 0.2; sqrt(3)**2 or euler’s identity;

WTH? help me :sob:

	var x = is_equal_approx((sqrt(2.0) * sqrt(2.0)), 2.0)
	print(x)

Write a big-math and/or fixed point class

ok, just wait, I’m gonna try them :victory_hand:

uh, bro? :frowning_face_with_open_mouth: is that extension workfull for my issue?

Floating point errors are kind of a fact of computing. You can reduce them with more bits, a 128-bit float would represent more fine-grained numbers, but there’s probably no good way to get those in Godot. Fixed point attempt to represent a different range of numbers, but still a limited amount. Some amount of rounding will take place.

Is there any specific issue you are trying to solve? What is the big picture, talking in game features what are you trying to do?

I was writing a program that relies TOO HARD on Boolean comparisons and strict adherence to mathematical principles;

therefore, I can’t simply program from the script that √2**2 o √2*√2 must be 2 or that Euler’s identity must be 0; because I don’t know what kind of input the user will be providing;

that’s why I discarded the ≈ operator a long time ago, to ensure that if operators like roots, logarithms, or divisions are used, or if constants are involved, it’s done with the understanding that the answer must be rational or exact, for example, π*1/π=1 or √3**2 =3

That’s not really what the “big picture” problem is. Why are you comparing floating point values by exact value?

I’m such a stupid newbie loser, I’m not good at programming :sad_but_relieved_face:

I don’t know what to do to fix this, I don’t know what to change, what to include, or what not to include.

I only know what I’d like to do if only this damn problem of lack of decimal precision didn’t exist :sob:

Read @sancho2 's answer carefully. Then read up more about the function that is called there:

Don’t panic. Learn about advanced numbers later.

(Edit) Unless you’re doing maths assignments in Godot, you will not need to write your own mathematical operations for most common things.

Like @gertkeno said: what is the picture. What do you want to rotate/translate/etc, talk about that.

@gertkeno is asking for a broader view of what your game mechanic is.
That knowledge will likely lead to an easier way to handle it.
I get the desire to keep your game idea to yourself but the more info you give up the better the answers get.
You should describe what the game is doing when you want these comparisons.

And stop beating yourself up; I see nothing in these questions of yours that isn’t legit.

t’s kinda Four fours puzzle, I mean, look:

The lack of decimal precision will invalidate more than one;

That’s why I said it depends a lot on both decimal precision and Boolean comparison, as well as being faithful to legitimate results, not those strange and illegitimate results.

How about rounding the results to let’s say 4th digit place? Usually the floating point errors start to show after 10th digit or so, and I don’t think you need more than 4 digit places in a puzzle game. This should get you covered.

We were all beginners at some point, and we don’t have all the answers either. You are definitely not a loser. There is a lot to learn, and you’re going to run into obstacles along the way. It’s part of the journey.

the problem is caused by how computers work, but i think you could fix it by ceiling value or flooring it to specific decimal point, e.g if you need 2 then you can do:

var ceiled = ceil(value * 10 + 0.1) / 10

e.g 1.99 * 10 + 0.1 = 19.9 + 0.1 = 20

20 / 10 = 2

Most math floating errors seem to happen at 0.99, not at .00001 so it should work for most things, you can also use round to remove errors more precisely, but ceil should work well enough

Describe exactly what it is, not what it “kinda” is.

oops, sorry you all, I was watching a video about the issue:

I guess I’ll just continue with the game; for now, I’ll ignore this thing that’s slowing me down.

I realized that most of the time this happens, it’s because it doesn’t have the programmed axiom that any number whose square root is squared is the same number; that, and also several additions or subtractions of fractions.

But I did PI*1/PI == 1, and it does say true

The moment you convert the textual sequence of digits into a float or double it’s already a “close-enough” approximation, not exactly equal to your original number.
Not only that, but when you write down stuff like f = log(8)/log(2), the script engine is actually approximating y = log(8), then approximating z = log(2), then approximating r = y/z… It strictly evaluates without doing the kind of clever conversion and short-circuiting seen in math books.
You can write some procedures that check the raw text of the input numbers and do some rule-checking on them. Here is an example of what i mean:

  • "6 / 3 + 9 / 3" tokenizes to "a b c d e f g", where a= number "6", b= operator "/", c= number "3", d= operator "+", e= number "9", f= operator "/", g= number "3".
  • "b c" = "f g" = "/ 3" = "div_by_3", as in: both two-token sequences are exactly he same thing, a division by 3.
  • thus, "a b c d e f g" = "a div_by_3 d e div_by_3".
  • "a div_by_3 d e div_by_3" = "a div_by_3 + e div_by_3" = "(a + e) div_by_3"

Long story short, doing these math evaluations will require your script to get smart about the text sequence and decode where are the numbers and operators, what operations are being done, who is equal, greater or lower, multiple, primes, which sequence is equal to which other sequence, so on so forth.

@sancho2 already suggested using is_equal_approx(), why don’t you use that? To me it looks like a very good solution to your problem. If the player writes an expression which results, let’s say, 2.38563, it is not approximately 2. If the player is able to write an expression where is_equal_approx(result, 2) == true, the result is very probably exactly 2.