How can I compare floats when they are equal?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Suleymanov
if float(Lap.text) < float(Best.text):
    print("update Best")

The problem is when they are equal it still prints “update Best”, when it only had to update when one is smaller. Numbers come with 3 decimals (eg: 13.578). When I print them they are exactly the same numbers, but it still says “update Best”. What’s the trick?

Edit: This didn’t help either: if float(lapTime.text) - float(bestLap.text) < 0.000:

Floating point numbers are imprecise. You shouldn’t use them for exact comparison.

exuin | 2021-04-15 17:44

Any alternative? - To compare numbers with decimals.

Suleymanov | 2021-04-15 17:54

:bust_in_silhouette: Reply From: Mario

I think you’ve got multiple issues here:

  • First of all, you’re converting text back to a number, which is something you should avoid. Why not store the actual numbers?
  • You shouldn’t have to constantly check whether the time has changed or is different. You know when it changes, so I’d absolutely go with signals instead.

This this from memory, so might include mistakes, but should give you a general idea on how I’d solve this (to be put into its own standalone script, e.g. score_tracker.gd):

extends Node
class_name ScoreTracker

signal highscore(best: float, previous: float)
var best: float
var first: bool = true
var inverted: bool

func reset() -> void:
    first = true

func track(score: float) -> void:
    if self.first or (self.inverted and self.best < score) or (self.best > score):
        self.first = false
        var previous = self.best
        self.best = score
        emit_signal("highscore", self.best, previous)

Once this is implemented, you can track scores using this new class:

var lap_tracker

func _ready() -> void:
    lap_tracker = ScoreTracker.new()
    lap_tracker.inverted = true
    lap_tracker.connect("highscore", self, "_on_highscore")

func _on_highscore(best: float, previous: float) -> void:
    # Update UI
    print("update Best")

# Whenever a lap finishes:
lap_tracker.track(time_as_float)

And yes, while this also ignores float imprecision, you shouldn’t get repeated events, unless you indeed got a tad bit faster, even if it’s just 1 microsecond.