1pub fn dot_i16(a: &[i16], b: &[i16]) -> i64 {
6 assert_eq!(a.len(), b.len(), "input slices must have the same length");
7
8 let mut sum: i64 = 0;
9 for (&x, &y) in a.iter().zip(b.iter()) {
10 sum = sum.wrapping_add((x as i32 as i64) * (y as i32 as i64));
11 }
12
13 sum
14}
15
16pub fn dot_i32(a: &[i32], b: &[i32]) -> i64 {
21 assert_eq!(a.len(), b.len(), "input slices must have the same length");
22
23 let mut sum: i64 = 0;
24 for (&x, &y) in a.iter().zip(b.iter()) {
25 let prod = ((x as i64) * (y as i64)) >> 14;
26 sum = sum.wrapping_add(prod);
27 }
28
29 sum
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35
36 #[test]
37 fn dot_i16_basic() {
38 let a = [0x4000_i16, 0x4000_i16]; let b = [0x4000_i16, 0x2000_i16]; let out = dot_i16(&a, &b);
42 assert_eq!(out, 402_653_184);
43 }
44
45 #[test]
46 fn dot_i32_basic() {
47 let a = [0x4000_0000_i32, 0x4000_0000_i32];
48 let b = [0x4000_0000_i32, 0x2000_0000_i32];
49
50 let out = dot_i32(&a, &b);
51 let expected = (((0x4000_0000_i64 * 0x4000_0000_i64) >> 14)
52 + ((0x4000_0000_i64 * 0x2000_0000_i64) >> 14)) as i64;
53 assert_eq!(out, expected);
54 }
55}