2026-10-01 23:43:34 +03:00
|
|
|
extends SceneTree
|
|
|
|
|
const E = preload("res://world/owniverse/math/exact.gd")
|
|
|
|
|
const B = preload("res://world/owniverse/math/big_integer.gd")
|
|
|
|
|
var checks: int = 0
|
|
|
|
|
var failures: int = 0
|
|
|
|
|
|
|
|
|
|
func verify(condition: bool, label: String):
|
|
|
|
|
checks += 1
|
|
|
|
|
if not condition:
|
|
|
|
|
failures += 1
|
|
|
|
|
push_error(label)
|
|
|
|
|
|
|
|
|
|
func _initialize():
|
|
|
|
|
call_deferred("run")
|
|
|
|
|
|
|
|
|
|
func run():
|
|
|
|
|
var rng = RandomNumberGenerator.new()
|
|
|
|
|
rng.seed = 619
|
|
|
|
|
for trial in 300:
|
|
|
|
|
var n: int = rng.randi_range(0, 100)
|
|
|
|
|
var m: int = rng.randi_range(1, 100)
|
|
|
|
|
var a: int = rng.randi_range(0, 1000)
|
|
|
|
|
var b: int = rng.randi_range(0, 1000)
|
|
|
|
|
var expected: int = 0
|
|
|
|
|
for i in n: expected += (a * i + b) / m
|
|
|
|
|
verify(E.eq(E.floor_sum(n, a, b, m), expected), "floor sum matches explicit windows")
|
|
|
|
|
var huge = E.of("1e40")
|
|
|
|
|
verify(E.lt(E.of("1e1000"), INF), "finite huge number is below positive infinity")
|
|
|
|
|
verify(E.gt(E.of("-1e1000"), -INF), "finite huge negative number is above negative infinity")
|
|
|
|
|
verify(E.gt(INF, E.of("1e1000")), "positive infinity is above finite huge number")
|
|
|
|
|
verify(not E.eq(E.of("1e1000"), INF), "huge number is not infinity")
|
|
|
|
|
verify(E.eq(E.floor_sum(huge, 2, 1, 2), E.divide(E.multiply(huge, E.subtract(huge, 1)), 2)), "floor sum supports huge window counts")
|
|
|
|
|
var rows = JSON.parse_string(FileAccess.get_file_as_string("res://tests/fixtures/big_integer_oracle.json"))
|
2026-10-05 22:16:59 +03:00
|
|
|
for row in rows.slice(0, 20):
|
|
|
|
|
var scaled = B.divmod(B.parse(row[0] + "000000000000000000"), B.parse(row[1] + "000000000000000000"))
|
|
|
|
|
verify(B.decimal(scaled[0]) == row[4], "cancel shared blocks preserves quotient")
|
|
|
|
|
verify(B.compare(scaled[1], B.multiply(B.parse(row[5]), B.parse("1000000000000000000"))) == 0, "cancel shared blocks restores original remainder")
|
2026-10-01 23:43:34 +03:00
|
|
|
for row in rows:
|
|
|
|
|
var a: Array = B.parse(row[0])
|
|
|
|
|
var b: Array = B.parse(row[1])
|
|
|
|
|
var qr: Array = B.divmod(a, b)
|
|
|
|
|
verify(B.decimal(B.add(a, b)) == row[2], "independent big sum")
|
|
|
|
|
verify(B.decimal(B.multiply(a, b)) == row[3], "independent big product")
|
|
|
|
|
verify(B.decimal(qr[0]) == row[4], "independent big quotient")
|
|
|
|
|
verify(B.decimal(qr[1]) == row[5], "independent big remainder")
|
|
|
|
|
verify(E.fixed(E.multiply(E.of(row[0]), E.of(row[1]))) == row[3], "dynamic product")
|
|
|
|
|
verify(E.eq(E.mul_div(E.of(row[0]), E.of(row[1]), E.of(row[1])), E.of(row[0])), "fused conservation")
|
|
|
|
|
for text in ["9223372036854775807", "-9223372036854775808", "9223372036854775808", "-9223372036854775809", "1e300", "1e1000"]:
|
|
|
|
|
var n = E.of(text)
|
|
|
|
|
verify(E.eq(E.subtract(E.add(n, 1), n), 1), "unit preserved at " + text)
|
|
|
|
|
verify(E.eq(E.decode(JSON.parse_string(JSON.stringify(E.encode(n)))), n), "round trip " + text)
|
|
|
|
|
for text in ["1.25", "-1.25", "123.5"]:
|
|
|
|
|
verify(E.approx(E.of(text)) == float(text), "approx fraction " + text)
|
|
|
|
|
verify(not E.valid_encoded({"$exact": [[], "0000000000000000", 1]}), "reject empty blocks")
|
|
|
|
|
verify(not E.valid_encoded({"$exact": [[1, 0], "0000000000000000", 1]}), "reject noncanonical blocks")
|
|
|
|
|
verify(E.gt(E.power(E.of("1e400"), -1), 0) == false, "float fraction underflows beyond its range")
|
|
|
|
|
verify(absf(E.approx(E.logarithm(E.of("1e1000"))) - 1000 * log(10.0)) < 1e-8, "logarithm beyond float range")
|
|
|
|
|
verify(E.eq(E.square_root(E.of("1e1000")), E.of("1e500")), "square root beyond float range")
|
|
|
|
|
var world = load("res://world/owniverse/owniverse.gd").new()
|
|
|
|
|
world.catalog.load_definitions(root.get_node("Global").OwniverseEntities)
|
|
|
|
|
for id in world.catalog.entities:
|
|
|
|
|
world.state.amount[id] = 0
|
|
|
|
|
world.state.stats.total_amount[id] = 0
|
|
|
|
|
var group: String = world.catalog.entities[id].group_as
|
|
|
|
|
if group != "":
|
|
|
|
|
world.state.amount[group] = 0
|
|
|
|
|
world.state.stats.total_amount[group] = 0
|
|
|
|
|
world.state.amount.H = E.of("1e1000")
|
|
|
|
|
world.state.amount.S = E.of("1e1000")
|
|
|
|
|
var environment: Dictionary = world.environment.stellar_environment(world.state)
|
|
|
|
|
verify(E.finite(environment.density) and E.gt(environment.density, 0), "huge density remains finite")
|
|
|
|
|
verify(E.near(environment.blast, 1), "huge geometric ratio stays valid")
|
|
|
|
|
for entity in world.catalog.entities.values(): entity.free()
|
|
|
|
|
world.free()
|
|
|
|
|
print("Dynamic math: %d checks, %d failures" % [checks, failures])
|
|
|
|
|
quit(1 if failures else 0)
|