Add exact arithmetic implementation and tests

- Introduced exact arithmetic with support for large integers and fractions in `exact.gd`, `big_integer.gd`, and `exact_value.gd`.
- Implemented a comprehensive test suite in `test_exact_math.gd` to validate arithmetic operations against expected results.
- Added a README in `math` directory to document the exact arithmetic system and its usage.
- Ensured that all arithmetic operations maintain precision without floating-point errors, using a custom representation for large numbers.
- Included methods for encoding and decoding exact values for serialization.
This commit is contained in:
Kirill
2026-09-30 08:08:27 +03:00
parent f2111a376a
commit fb8a3f5658
58 changed files with 5139 additions and 2162 deletions
+20 -19
View File
@@ -1,4 +1,5 @@
extends SceneTree
const E = preload("res://world/owniverse/math/exact.gd")
const Clock = preload("res://world/owniverse/simulation_time.gd")
var checks: int = 0
var failures: int = 0
@@ -7,9 +8,9 @@ func _initialize() -> void:
call_deferred("run")
func check(condition: bool, message: String) -> void:
checks += 1
if not condition:
failures += 1
checks = E.add(checks, 1)
if (not condition):
failures = E.add(failures, 1)
push_error(message)
func fixture():
@@ -18,16 +19,16 @@ func fixture():
for id in global.OwniverseEntities:
var entity = load("res://world/owniverse/owniverse_entity.gd").new(global.OwniverseEntities[id])
world.catalog.entities[id] = entity
world.state.amount[id] = 0.0
world.state.stats.total_amount[id] = 0.0
if entity.group_as != "":
world.state.amount[entity.group_as] = 0.0
world.state.stats.total_amount[entity.group_as] = 0.0
world.state.amount[id] = 0
world.state.stats.total_amount[id] = 0
if E.ne(entity.group_as, ""):
world.state.amount[entity.group_as] = 0
world.state.stats.total_amount[entity.group_as] = 0
world.catalog.entities["N"].life_product = {}
world.catalog.entities["N"].product_per_year_type = "H"
world.catalog.entities["N"].product_per_year_amount = 10.0
world.catalog.entities["N"].auto = 0.0
world.state.amount.N = 1.0
world.catalog.entities["N"].product_per_year_amount = 10
world.catalog.entities["N"].auto = 0
world.state.amount.N = 1
return world
func dispose(world) -> void:
@@ -40,19 +41,19 @@ func run() -> void:
for id in world.catalog.entities:
var expected: Array = []
for key in world.catalog.entities:
if world.catalog.entities[key].group_as == id:
if E.eq(world.catalog.entities[key].group_as, id):
expected.append(key)
check(world.catalog.is_group(id) == (not expected.is_empty()), "Group classification: " + id)
check(world.catalog.members(id) == (expected if not expected.is_empty() else [id]), "Group members: " + id)
check(E.eq(world.catalog.is_group(id), ((not expected.is_empty()))), E.add("Group classification: ", id))
check(E.eq(world.catalog.members(id), ((expected if (not expected.is_empty()) else [id]))), E.add("Group members: ", id))
var members: Array = world.catalog.members("Star")
members.clear()
check(not world.catalog.members("Star").is_empty(), "Returned members are independent")
check((not world.catalog.members("Star").is_empty()), "Returned members are independent")
world.catalog.entities.N.group_as = "TestGroup"
world.catalog.rebuild_group_index()
check(world.catalog.members("TestGroup") == ["N"], "Explicit definition reload")
check(E.eq(world.catalog.members("TestGroup"), ["N"]), "Explicit definition reload")
world.catalog.entities.N.free()
world.catalog.entities.erase("N")
check(not world.catalog.is_group("TestGroup"), "Removed definition invalidates index")
print("Group index: %d checks, %d failures" % [checks, failures])
check((not world.catalog.is_group("TestGroup")), "Removed definition invalidates index")
print(("Group index: %d checks, %d failures" % [checks, failures]))
dispose(world)
quit(1 if failures else 0)
quit((1 if failures else 0))