Describe the bug
ScalarValue::eq_array is documented as an optimized equivalent of extracting an array element with ScalarValue::try_from_array and comparing the resulting scalars. However, for floating-point values eq_array uses IEEE equality while ScalarValue::PartialEq compares bit representations, producing inconsistent results:
- Identical NaN bit patterns compare equal as
ScalarValues but unequal through eq_array.
+0.0 and -0.0 compare unequal as ScalarValues but equal through eq_array.
This bug was discovered by the randomized ScalarValue array-conversion coverage added in #24433.
To Reproduce
Compare these scalars with the corresponding Float64 array elements:
ScalarValue(NaN).eq_array([NaN], 0) = false
ScalarValue(+0.0).eq_array([-0.0], 0) = true
In contrast, extracting those elements with ScalarValue::try_from_array and using ScalarValue::eq considers the identical NaN equal and the two signed zeros unequal.
Expected behavior
ScalarValue::eq_array should have the same floating-point equality semantics as ScalarValue::PartialEq:
- Identical NaN bit patterns should compare equal.
- Different NaN bit patterns should remain distinct.
+0.0 and -0.0 should remain distinct.
Additional context
ScalarValue implements Eq and Hash, and its float hashes and ordering are based on bit representations/total ordering. Changing ScalarValue::PartialEq to IEEE equality would violate Eq reflexivity for NaNs and require coordinated changes to hashing and ordering. The narrow fix is therefore to make the Float16, Float32, and Float64 branches of eq_array compare to_bits() values.
Describe the bug
ScalarValue::eq_arrayis documented as an optimized equivalent of extracting an array element withScalarValue::try_from_arrayand comparing the resulting scalars. However, for floating-point valueseq_arrayuses IEEE equality whileScalarValue::PartialEqcompares bit representations, producing inconsistent results:ScalarValues but unequal througheq_array.+0.0and-0.0compare unequal asScalarValues but equal througheq_array.This bug was discovered by the randomized
ScalarValuearray-conversion coverage added in #24433.To Reproduce
Compare these scalars with the corresponding Float64 array elements:
In contrast, extracting those elements with
ScalarValue::try_from_arrayand usingScalarValue::eqconsiders the identical NaN equal and the two signed zeros unequal.Expected behavior
ScalarValue::eq_arrayshould have the same floating-point equality semantics asScalarValue::PartialEq:+0.0and-0.0should remain distinct.Additional context
ScalarValueimplementsEqandHash, and its float hashes and ordering are based on bit representations/total ordering. ChangingScalarValue::PartialEqto IEEE equality would violateEqreflexivity for NaNs and require coordinated changes to hashing and ordering. The narrow fix is therefore to make the Float16, Float32, and Float64 branches ofeq_arraycompareto_bits()values.