Skip to content

Commit a12cf5e

Browse files
big_integer/multiply: improve docs, validation, and clarity
Signed-off-by: KushalMeghani1644 <kushalmeghani108@gmail.com>
1 parent 4eec0b7 commit a12cf5e

1 file changed

Lines changed: 53 additions & 31 deletions

File tree

src/big_integer/multiply.rs

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,94 @@
1-
/// Performs long multiplication on string representations of non-negative numbers.
1+
/// Performs long multiplication on string representations of non-negative base-10 integers.
2+
///
3+
/// # Panics
4+
/// Panics if either input contains non-ASCII digits, leading zeros (except "0"),
5+
/// or is empty.
6+
///
7+
/// # Examples
8+
/// ```
9+
/// use crate::big_integer::multiply;
10+
/// assert_eq!(multiply("123", "456"), "56088");
11+
/// assert_eq!(multiply("99", "99"), "9801");
12+
/// ```
213
pub fn multiply(num1: &str, num2: &str) -> String {
3-
if !is_valid_nonnegative(num1) || !is_valid_nonnegative(num2) {
4-
panic!("String does not conform to specification")
14+
if !is_valid_nonnegative(num1) {
15+
panic!("Invalid input: `{num1}` is not a valid non-negative integer string");
16+
}
17+
if !is_valid_nonnegative(num2) {
18+
panic!("Invalid input: `{num2}` is not a valid non-negative integer string");
519
}
620

721
if num1 == "0" || num2 == "0" {
822
return "0".to_string();
923
}
10-
let output_size = num1.len() + num2.len();
1124

25+
let output_size = num1.len() + num2.len();
1226
let mut mult = vec![0; output_size];
27+
1328
for (i, c1) in num1.chars().rev().enumerate() {
1429
for (j, c2) in num2.chars().rev().enumerate() {
1530
let mul = c1.to_digit(10).unwrap() * c2.to_digit(10).unwrap();
16-
// It could be a two-digit number here.
17-
mult[i + j + 1] += (mult[i + j] + mul) / 10;
18-
// Handling rounding. Here's a single digit.
19-
mult[i + j] = (mult[i + j] + mul) % 10;
31+
let sum = mult[i + j] + mul;
32+
33+
mult[i + j + 1] += sum / 10;
34+
mult[i + j] = sum % 10;
2035
}
2136
}
37+
2238
if mult[output_size - 1] == 0 {
2339
mult.pop();
2440
}
2541
mult.iter().rev().map(|&n| n.to_string()).collect()
2642
}
2743

44+
/// Checks whether a string represents a valid non-negative base-10 integer.
45+
/// Disallows empty strings, leading zeros (except "0"), and non-ASCII digits.
2846
pub fn is_valid_nonnegative(num: &str) -> bool {
29-
num.chars().all(char::is_numeric) && !num.is_empty() && (!num.starts_with('0') || num == "0")
47+
!num.is_empty()
48+
&& num.chars().all(|c| c.is_ascii_digit())
49+
&& (!num.starts_with('0') || num == "0")
3050
}
3151

3252
#[cfg(test)]
3353
mod tests {
3454
use super::*;
55+
3556
macro_rules! test_multiply {
3657
($($name:ident: $inputs:expr,)*) => {
37-
$(
38-
#[test]
39-
fn $name() {
40-
let (s, t, expected) = $inputs;
41-
assert_eq!(multiply(s, t), expected);
42-
assert_eq!(multiply(t, s), expected);
43-
}
44-
)*
58+
$(
59+
#[test]
60+
fn $name() {
61+
let (s, t, expected) = $inputs;
62+
assert_eq!(multiply(s, t), expected, "multiply({s}, {t})");
63+
assert_eq!(multiply(t, s), expected, "multiply({t}, {s})");
64+
}
65+
)*
4566
}
4667
}
4768

4869
test_multiply! {
49-
multiply0: ("2", "3", "6"),
50-
multiply1: ("123", "456", "56088"),
70+
multiply_small: ("2", "3", "6"),
71+
multiply_basic: ("123", "456", "56088"),
5172
multiply_zero: ("0", "222", "0"),
52-
other_1: ("99", "99", "9801"),
53-
other_2: ("999", "99", "98901"),
54-
other_3: ("9999", "99", "989901"),
55-
other_4: ("192939", "9499596", "1832842552644"),
73+
multiply_double_digits: ("99", "99", "9801"),
74+
multiply_triple_digits: ("999", "99", "98901"),
75+
multiply_four_digits: ("9999", "99", "989901"),
76+
multiply_large: ("192939", "9499596", "1832842552644"),
5677
}
5778

5879
macro_rules! test_multiply_with_wrong_input {
5980
($($name:ident: $inputs:expr,)*) => {
60-
$(
61-
#[test]
62-
#[should_panic]
63-
fn $name() {
64-
let (s, t) = $inputs;
65-
multiply(s, t);
66-
}
67-
)*
81+
$(
82+
#[test]
83+
#[should_panic]
84+
fn $name() {
85+
let (s, t) = $inputs;
86+
multiply(s, t);
87+
}
88+
)*
6889
}
6990
}
91+
7092
test_multiply_with_wrong_input! {
7193
empty_input: ("", "121"),
7294
leading_zero: ("01", "3"),

0 commit comments

Comments
 (0)