Skip to content

Commit b1c69d3

Browse files
committed
Use to_bits comparison to check if a float value can be represented as an integer losslessly.
This allows to simplify the code while still maintaining "negative zeros" edge case. Thanks @JasonHise for the suggestion.
1 parent 841bd33 commit b1c69d3

File tree

6 files changed

+19
-23
lines changed

6 files changed

+19
-23
lines changed

mlua-sys/src/lua51/compat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
187187
let n = lua_tonumber(L, idx);
188188
let i = lua_tointeger(L, idx);
189189
// Lua 5.3+ returns "false" for `-0.0`
190-
if (n - i as lua_Number).abs() < lua_Number::EPSILON && !(n == 0.0 && n.is_sign_negative()) {
190+
if n.to_bits() == (i as lua_Number).to_bits() {
191191
return 1;
192192
}
193193
}

mlua-sys/src/lua52/compat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
5252
let n = lua_tonumber(L, idx);
5353
let i = lua_tointeger(L, idx);
5454
// Lua 5.3+ returns "false" for `-0.0`
55-
if (n - i as lua_Number).abs() < lua_Number::EPSILON && !(n == 0.0 && n.is_sign_negative()) {
55+
if n.to_bits() == (i as lua_Number).to_bits() {
5656
return 1;
5757
}
5858
}

mlua-sys/src/luau/compat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
121121
let n = lua_tonumber(L, idx);
122122
let i = lua_tointeger(L, idx);
123123
// Lua 5.3+ returns "false" for `-0.0`
124-
if (n - i as lua_Number).abs() < lua_Number::EPSILON && !(n == 0.0 && n.is_sign_negative()) {
124+
if n.to_bits() == (i as lua_Number).to_bits() {
125125
return 1;
126126
}
127127
}

src/state/raw.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -726,13 +726,9 @@ impl RawLua {
726726
ffi::LUA_TNUMBER => {
727727
use crate::types::Number;
728728

729-
fn same(n: Number, i: Integer) -> bool {
730-
(n - (i as Number)).abs() < Number::EPSILON && !(n == 0.0 && n.is_sign_negative())
731-
}
732-
733729
let n = ffi::lua_tonumber(state, idx);
734730
match num_traits::cast(n) {
735-
Some(i) if same(n, i) => Value::Integer(i),
731+
Some(i) if n.to_bits() == (i as Number).to_bits() => Value::Integer(i),
736732
_ => Value::Number(n),
737733
}
738734
}

tests/conversion.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -372,21 +372,6 @@ fn test_float_from_lua() -> Result<()> {
372372
// Should fallback to default conversion
373373
assert_eq!(f.call::<f32>("42.0")?, 42.0);
374374

375-
// Negative zero
376-
let negative_zero = lua.load("return -0.0").eval::<f64>()?;
377-
assert_eq!(negative_zero, 0.0);
378-
// LuaJIT treats -0.0 as a positive zero
379-
#[cfg(not(feature = "luajit"))]
380-
assert!(negative_zero.is_sign_negative());
381-
382-
// In Lua <5.3 all numbers are floats
383-
#[cfg(not(any(feature = "lua54", feature = "lua53", feature = "luajit")))]
384-
{
385-
let negative_zero = lua.load("return -0").eval::<f64>()?;
386-
assert_eq!(negative_zero, 0.0);
387-
assert!(negative_zero.is_sign_negative());
388-
}
389-
390375
Ok(())
391376
}
392377

tests/tests.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,21 @@ fn test_num_conversion() -> Result<()> {
602602

603603
assert_eq!(lua.unpack::<i128>(lua.pack(1i128 << 64)?)?, 1i128 << 64);
604604

605+
// Negative zero
606+
let negative_zero = lua.load("-0.0").eval::<f64>()?;
607+
assert_eq!(negative_zero, 0.0);
608+
// LuaJIT treats -0.0 as a positive zero
609+
#[cfg(not(feature = "luajit"))]
610+
assert!(negative_zero.is_sign_negative());
611+
612+
// In Lua <5.3 all numbers are floats
613+
#[cfg(not(any(feature = "lua54", feature = "lua53", feature = "luajit")))]
614+
{
615+
let negative_zero = lua.load("-0").eval::<f64>()?;
616+
assert_eq!(negative_zero, 0.0);
617+
assert!(negative_zero.is_sign_negative());
618+
}
619+
605620
Ok(())
606621
}
607622

0 commit comments

Comments
 (0)