mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-03-30 05:23:37 +08:00
fix(number-convert): preserve int precision for large numbers (#13147)
This commit is contained in:
parent
3b15651bc6
commit
6580a6bc01
@ -44,8 +44,13 @@ class NumberConvertNode(io.ComfyNode):
|
|||||||
def execute(cls, value) -> io.NodeOutput:
|
def execute(cls, value) -> io.NodeOutput:
|
||||||
if isinstance(value, bool):
|
if isinstance(value, bool):
|
||||||
float_val = 1.0 if value else 0.0
|
float_val = 1.0 if value else 0.0
|
||||||
elif isinstance(value, (int, float)):
|
int_val = 1 if value else 0
|
||||||
|
elif isinstance(value, int):
|
||||||
float_val = float(value)
|
float_val = float(value)
|
||||||
|
int_val = value
|
||||||
|
elif isinstance(value, float):
|
||||||
|
float_val = value
|
||||||
|
int_val = int(value)
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, str):
|
||||||
text = value.strip()
|
text = value.strip()
|
||||||
if not text:
|
if not text:
|
||||||
@ -56,6 +61,14 @@ class NumberConvertNode(io.ComfyNode):
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Cannot convert string to number: {value!r}"
|
f"Cannot convert string to number: {value!r}"
|
||||||
) from None
|
) from None
|
||||||
|
if not math.isfinite(float_val):
|
||||||
|
raise ValueError(
|
||||||
|
f"Cannot convert non-finite value to number: {float_val}"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
int_val = int(text)
|
||||||
|
except ValueError:
|
||||||
|
int_val = int(float_val)
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
f"Unsupported input type: {type(value).__name__}"
|
f"Unsupported input type: {type(value).__name__}"
|
||||||
@ -66,7 +79,7 @@ class NumberConvertNode(io.ComfyNode):
|
|||||||
f"Cannot convert non-finite value to number: {float_val}"
|
f"Cannot convert non-finite value to number: {float_val}"
|
||||||
)
|
)
|
||||||
|
|
||||||
return io.NodeOutput(float_val, int(float_val))
|
return io.NodeOutput(float_val, int_val)
|
||||||
|
|
||||||
|
|
||||||
class NumberConvertExtension(ComfyExtension):
|
class NumberConvertExtension(ComfyExtension):
|
||||||
|
|||||||
@ -90,6 +90,63 @@ class TestNumberConvertExecute:
|
|||||||
assert result[0] == 1000.0
|
assert result[0] == 1000.0
|
||||||
assert result[1] == 1000
|
assert result[1] == 1000
|
||||||
|
|
||||||
|
# --- Large number precision (string input) ---
|
||||||
|
|
||||||
|
def test_string_large_int_above_2_53(self):
|
||||||
|
"""Text-to-int must not lose precision for integers beyond 2^53."""
|
||||||
|
big = 2**53 + 1 # 9007199254740993
|
||||||
|
result = self._exec(str(big))
|
||||||
|
assert result[1] == big
|
||||||
|
|
||||||
|
def test_string_large_negative_int_above_2_53(self):
|
||||||
|
big = -(2**53 + 1)
|
||||||
|
result = self._exec(str(big))
|
||||||
|
assert result[1] == big
|
||||||
|
|
||||||
|
def test_string_very_large_int(self):
|
||||||
|
big = 2**63 + 42
|
||||||
|
result = self._exec(str(big))
|
||||||
|
assert result[1] == big
|
||||||
|
|
||||||
|
def test_string_large_int_float_output_is_float(self):
|
||||||
|
"""FLOAT output is still a float (may lose precision, but must be float type)."""
|
||||||
|
result = self._exec(str(2**53 + 1))
|
||||||
|
assert isinstance(result[0], float)
|
||||||
|
|
||||||
|
# --- Large number precision (int input) ---
|
||||||
|
|
||||||
|
def test_int_large_above_2_53(self):
|
||||||
|
"""Native int input must preserve its value in the INT output."""
|
||||||
|
big = 2**53 + 1
|
||||||
|
result = self._exec(big)
|
||||||
|
assert result[1] == big
|
||||||
|
|
||||||
|
def test_int_large_negative_above_2_53(self):
|
||||||
|
big = -(2**53 + 1)
|
||||||
|
result = self._exec(big)
|
||||||
|
assert result[1] == big
|
||||||
|
|
||||||
|
def test_int_very_large(self):
|
||||||
|
big = 2**100
|
||||||
|
result = self._exec(big)
|
||||||
|
assert result[1] == big
|
||||||
|
|
||||||
|
# --- String decimal / scientific notation fallback ---
|
||||||
|
|
||||||
|
def test_string_decimal_still_truncates(self):
|
||||||
|
"""Strings with decimal points fall back to int(float(...)) truncation."""
|
||||||
|
result = self._exec("3.7")
|
||||||
|
assert result[1] == 3
|
||||||
|
|
||||||
|
def test_string_negative_decimal_truncates(self):
|
||||||
|
result = self._exec("-2.9")
|
||||||
|
assert result[1] == -2
|
||||||
|
|
||||||
|
def test_string_scientific_large(self):
|
||||||
|
result = self._exec("1e18")
|
||||||
|
assert result[0] == 1e18
|
||||||
|
assert result[1] == 10**18
|
||||||
|
|
||||||
# --- STRING error paths ---
|
# --- STRING error paths ---
|
||||||
|
|
||||||
def test_empty_string_raises(self):
|
def test_empty_string_raises(self):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user