spawn_bitmath/
lib.rs

1use wasm_bindgen::prelude::*;
2use serde::{Deserialize, Serialize};
3use serde_wasm_bindgen::{from_value, to_value};
4
5/// Serde ile `u128` serileştirilmesi ve deseralize edilmesi için yapı.
6/// WebAssembly'de `u128`'i işler hale getirmek için kullanılır.
7#[derive(Serialize, Deserialize)]
8pub struct U128Wrapper {
9    value: u128,
10}
11
12/// Computes the index of the most significant bit of the u128 number.
13/// The least significant bit is at index 0, and the most significant bit is at index 127.
14///
15/// # Arguments
16/// * `input` - Serde ile serileştirilen u128 değeri.
17///
18/// # Returns
19/// The index of the most significant bit.
20#[wasm_bindgen]
21pub fn most_significant_bit(input: &JsValue) -> Result<JsValue, JsValue> {
22    let wrapper: U128Wrapper = from_value(input.clone()).map_err(|e| JsValue::from_str(&format!("Invalid input: {}", e)))?;
23    let value = wrapper.value;
24
25    if value == 0 {
26        return Err(JsValue::from_str("Input must be greater than 0"));
27    }
28
29    let mut x = value;
30    let mut r: u8 = 0;
31
32    if x >= 0x10000000000000000 {
33        x >>= 64;
34        r += 64;
35    }
36    if x >= 0x100000000 {
37        x >>= 32;
38        r += 32;
39    }
40    if x >= 0x10000 {
41        x >>= 16;
42        r += 16;
43    }
44    if x >= 0x100 {
45        x >>= 8;
46        r += 8;
47    }
48    if x >= 0x10 {
49        x >>= 4;
50        r += 4;
51    }
52    if x >= 0x4 {
53        x >>= 2;
54        r += 2;
55    }
56    if x >= 0x2 {
57        r += 1;
58    }
59
60    to_value(&r).map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
61}
62
63/// Computes the index of the least significant bit of the u128 number.
64/// The least significant bit is at index 0, and the most significant bit is at index 127.
65///
66/// # Arguments
67/// * `input` - Serde ile serileştirilen u128 değeri.
68///
69/// # Returns
70/// The index of the least significant bit.
71#[wasm_bindgen]
72pub fn least_significant_bit(input: &JsValue) -> Result<JsValue, JsValue> {
73    let wrapper: U128Wrapper = from_value(input.clone()).map_err(|e| JsValue::from_str(&format!("Invalid input: {}", e)))?;
74    let value = wrapper.value;
75
76    if value == 0 {
77        return Err(JsValue::from_str("Input must be greater than 0"));
78    }
79
80    let mut x = value;
81    let mut r: u8 = 127;
82
83    if x & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF > 0 {
84        r -= 64;
85    } else {
86        x >>= 64;
87    }
88    if x & 0xFFFFFFFF > 0 {
89        r -= 32;
90    } else {
91        x >>= 32;
92    }
93    if x & 0xFFFF > 0 {
94        r -= 16;
95    } else {
96        x >>= 16;
97    }
98    if x & 0xFF > 0 {
99        r -= 8;
100    } else {
101        x >>= 8;
102    }
103    if x & 0xF > 0 {
104        r -= 4;
105    } else {
106        x >>= 4;
107    }
108    if x & 0x3 > 0 {
109        r -= 2;
110    } else {
111        x >>= 2;
112    }
113    if x & 0x1 > 0 {
114        r -= 1;
115    }
116
117    to_value(&r).map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
118}
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123    use serde_wasm_bindgen::to_value;
124
125    #[test]
126    fn test_most_significant_bit() {
127        let input = U128Wrapper { value: 128 };
128        let input_js = to_value(&input).unwrap();
129        assert_eq!(most_significant_bit(&input_js).unwrap(), JsValue::from(7));
130    }
131
132    #[test]
133    fn test_least_significant_bit() {
134        let input = U128Wrapper { value: 16 };
135        let input_js = to_value(&input).unwrap();
136        assert_eq!(least_significant_bit(&input_js).unwrap(), JsValue::from(4));
137    }
138
139    #[test]
140    fn test_invalid_input() {
141        let input = U128Wrapper { value: 0 };
142        let input_js = to_value(&input).unwrap();
143        assert!(most_significant_bit(&input_js).is_err());
144        assert!(least_significant_bit(&input_js).is_err());
145    }
146}