cairo_vm/hint_processor/builtin_hint_processor/
garaga.rs

1use crate::stdlib::collections::HashMap;
2use crate::stdlib::prelude::String;
3
4use crate::{
5    hint_processor::hint_processor_definition::HintReference,
6    serde::deserialize_program::ApTracking,
7    vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
8};
9
10use super::hint_utils::{get_integer_from_var_name, insert_value_from_var_name};
11
12/// Implements hint:
13/// ```python
14/// x = ids.x,
15/// ids.bit_length = x.bit_length()
16/// ```
17pub fn get_felt_bitlenght(
18    vm: &mut VirtualMachine,
19    ids_data: &HashMap<String, HintReference>,
20    ap_tracking: &ApTracking,
21) -> Result<(), HintError> {
22    let x = get_integer_from_var_name("x", vm, ids_data, ap_tracking)?;
23    insert_value_from_var_name("bit_length", x.bits(), vm, ids_data, ap_tracking)
24}
25
26#[cfg(test)]
27mod tests {
28    use crate::any_box;
29    use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor;
30    use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData;
31    use crate::hint_processor::hint_processor_definition::HintProcessorLogic;
32    use crate::Felt252;
33    use crate::{hint_processor::builtin_hint_processor::hint_code, utils::test_utils::*};
34
35    #[cfg(target_arch = "wasm32")]
36    use wasm_bindgen_test::*;
37
38    use super::*;
39
40    fn run_hint(x: Felt252) -> Result<Felt252, HintError> {
41        let ids_data = non_continuous_ids_data![
42            ("x", 0),          // located at `fp + 0`.
43            ("bit_length", 1)  // located at `fp + 1`.
44        ];
45
46        let mut vm = vm!();
47        vm.run_context.fp = 0;
48        add_segments!(vm, 2); // Alloc space for `ids.x` and `ids.bit_length`
49        vm.insert_value((1, 0).into(), x).unwrap();
50
51        run_hint!(vm, ids_data, hint_code::GET_FELT_BIT_LENGTH).unwrap();
52        Ok(vm.get_integer((1, 1).into()).unwrap().into_owned())
53    }
54
55    #[test]
56    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
57    fn test_simple() {
58        let bit_length_result = run_hint(Felt252::from(7));
59        assert!(bit_length_result.is_ok());
60        assert_eq!(bit_length_result.unwrap(), Felt252::from(3));
61    }
62
63    #[test]
64    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
65    fn test_in_range() {
66        for i in 0..252_u32 {
67            let x: Felt252 = Felt252::TWO.pow(i);
68
69            let bit_length_result = run_hint(x);
70            assert!(bit_length_result.is_ok());
71            assert_eq!(bit_length_result.unwrap(), Felt252::from(i + 1));
72        }
73    }
74
75    #[test]
76    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
77    fn test_wraparound() {
78        let x = Felt252::MAX + Felt252::ONE;
79        let bit_length_result = run_hint(x);
80        assert!(bit_length_result.is_ok());
81        assert_eq!(bit_length_result.unwrap(), Felt252::ZERO);
82    }
83}