Skip to content

Commit 6b2d294

Browse files
authored
Fix BoundedInt is_zero libfunc (#1464)
* Fix is_zero for bounded ints * Refactor * Add comment
1 parent 1980a4f commit 6b2d294

1 file changed

Lines changed: 59 additions & 1 deletion

File tree

src/libfuncs/bounded_int.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,13 @@ fn build_is_zero<'ctx, 'this>(
815815
"value can never be zero"
816816
);
817817

818-
let k0 = entry.const_int_from_type(context, location, 0, src_value.r#type())?;
818+
let k0 = if src_ty.is_bounded_int(registry)? {
819+
// We can do the substraction since the lower bound of the bounded int will
820+
// always be less or equal than 0.
821+
entry.const_int_from_type(context, location, 0 - src_range.lower, src_value.r#type())?
822+
} else {
823+
entry.const_int_from_type(context, location, 0, src_value.r#type())?
824+
};
819825
let src_is_zero = entry.cmpi(context, CmpiPredicate::Eq, src_value, k0, location)?;
820826

821827
helper.cond_br(
@@ -1001,6 +1007,58 @@ mod test {
10011007
assert_eq!(value, Felt252::from(0));
10021008
}
10031009

1010+
fn assert_bool_output(result: Value, expected_tag: usize) {
1011+
if let Value::Enum { tag, value, .. } = result {
1012+
assert_eq!(tag, 0);
1013+
if let Value::Struct { fields, .. } = *value {
1014+
if let Value::Enum { tag, .. } = fields[0] {
1015+
assert_eq!(tag, expected_tag)
1016+
}
1017+
}
1018+
}
1019+
}
1020+
1021+
#[test]
1022+
fn test_is_zero() {
1023+
let program = load_cairo! {
1024+
#[feature("bounded-int-utils")]
1025+
use core::internal::bounded_int::{self, BoundedInt, is_zero};
1026+
use core::zeroable::IsZeroResult;
1027+
1028+
fn run_test_1(a: felt252) -> bool {
1029+
let bi: BoundedInt<0, 5> = a.try_into().unwrap();
1030+
match is_zero(bi) {
1031+
IsZeroResult::Zero => true,
1032+
IsZeroResult::NonZero(_) => false,
1033+
}
1034+
}
1035+
1036+
fn run_test_2(a: felt252) -> bool {
1037+
let bi: BoundedInt<-5, 5> = a.try_into().unwrap();
1038+
match is_zero(bi) {
1039+
IsZeroResult::Zero => true,
1040+
IsZeroResult::NonZero(_) => false,
1041+
}
1042+
}
1043+
};
1044+
1045+
let result =
1046+
run_program(&program, "run_test_1", &[Value::Felt252(Felt252::from(0))]).return_value;
1047+
assert_bool_output(result, 1);
1048+
1049+
let result =
1050+
run_program(&program, "run_test_1", &[Value::Felt252(Felt252::from(5))]).return_value;
1051+
assert_bool_output(result, 0);
1052+
1053+
let result =
1054+
run_program(&program, "run_test_2", &[Value::Felt252(Felt252::from(0))]).return_value;
1055+
assert_bool_output(result, 1);
1056+
1057+
let result =
1058+
run_program(&program, "run_test_2", &[Value::Felt252(Felt252::from(-5))]).return_value;
1059+
assert_bool_output(result, 0);
1060+
}
1061+
10041062
fn assert_constrain_output(result: Value, expected_bi: Value) {
10051063
if let Value::Enum { tag, value, .. } = result {
10061064
assert_eq!(tag, 0);

0 commit comments

Comments
 (0)