Решение на Bigint от Борис Петров

Обратно към всички решения

Към профила на Борис Петров

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 8 успешни тест(а)
  • 7 неуспешни тест(а)

Код

use std::cmp::Ordering;
use std::ops::{Add, Sub};
use std::str::FromStr;
#[derive(Debug)]
pub struct ParseError;
#[derive(Debug, PartialEq, Eq)]
pub struct Bigint {
sign: i8,
digits: Vec<u8>,
}
impl Bigint {
/// Конструира нов Bigint със стойност "0" и положителен знак.
/// Това може да означава празен вектор с цифри или масив с една цифра `0` -- ваш избор.
///
pub fn new() -> Self {
Bigint {
sign: 1,
digits: vec![0],
}
}
/// Конструира нов Bigint с подадените цифри и знак.
///
/// Тук е добро място където можете да вкарате малко валидация и нормализиране на входа -- да
/// премахнете допълнителни нули или да се погрижите, че нулата винаги има консистентен знак.
/// Стига да се погрижите винаги да използвате функцията при конструириане на нови Bigint-ове.
///
/// Тази функция НЕ Е публична, така че НЕ Е задължителна -- ако не ви трябва, може смело да я
/// изтриете.
///
pub fn from_components(digits: Vec<u8>, sign: i8) -> Self {
let mut new_sign: i8 = sign;
let mut new_digits = digits;
if sign != -1 && sign != 1 {
panic!("Sign can only be -1 or 1")
}
// if vector is empty make the element 0
if new_digits.len() < 1 {
new_digits = vec![0];
}
// zeroes are positive!
if new_digits == vec![0] {
new_sign = 1;
}
// remove starting zeros (ex. 000123 = 123)
loop {
if new_digits == vec![0] || new_digits[0] != 0 {
break;
}
new_digits.remove(0);
}
Bigint {
sign: new_sign,
digits: new_digits,
}
}
/// Връща `true` ако числото е положително. Нулата не е положителна.
pub fn is_positive(&self) -> bool {
self.sign == 1 && self.digits != vec![0]
}
/// Връща `true` ако числото е отрицателно. Нулата не е отрицателна.
pub fn is_negative(&self) -> bool {
self.sign == -1
}
}
impl FromStr for Bigint {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let sign: i8;
let mut digits: Vec<u8> = Vec::new();
match s.chars().nth(0) {
Some('+') => {
sign = 1;
// this should be in a function but no time :)
for (index, c) in s.chars().enumerate() {
if index != 0 {
if !c.is_digit(10) {
return Err(ParseError);
}
digits.push(c.to_digit(10).unwrap() as u8);
}
}
return Ok(Bigint::from_components(digits, sign));
}
Some('-') => {
sign = -1;
for (index, c) in s.chars().enumerate() {
if index != 0 {
if !c.is_digit(10) {
return Err(ParseError);
}
digits.push(c.to_digit(10).unwrap() as u8);
}
}
return Ok(Bigint::from_components(digits, sign));
}
_ => {
sign = 1;
for c in s.chars() {
if !c.is_digit(10) {
return Err(ParseError);
}
digits.push(c.to_digit(10).unwrap() as u8);
}
return Ok(Bigint::from_components(digits, sign));
}
};
}
}
impl PartialOrd for Bigint {
fn partial_cmp(&self, other: &Bigint) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Bigint {
/// Ако едното от числата има по-голям брой цифри, то ще бъде по-голямото. (Стига да не са нули
/// -- вероятно е добра идея да се погрижите да няма започващи нули при конструкция.)
///
/// Ако двете числа имат еднакъв брой цифри, лексикографско сравнение на числата ще ви даде
/// правилен резултат -- от по-значимите цифри към по-малко значимите. Внимавайте в какъв ред
/// си държите цифритe и дали не трябва да ги обърнете.
///
/// Ако двете числа са отрицателни, сравнението по абсолютна стойност ще е обърнато (-1 е
/// по-голямо от -2) -- погледнете документацията на `Ordering` за това как лесно можете да
/// обърнете резултата.
///
fn cmp(&self, other: &Bigint) -> Ordering {
if self.sign == other.sign {
if self.sign == 1 {
if self.digits.len() > other.digits.len() {
return Ordering::Greater;
} else if self.digits.len() < other.digits.len() {
return Ordering::Less;
} else {
for (i, num) in self.digits.iter().enumerate() {
if num != &other.digits[i] {
if num > &other.digits[i] {
return Ordering::Greater;
} else {
return Ordering::Less;
}
}
}
return Ordering::Equal;
}
}
} else {
if self.sign == 1 {
return Ordering::Greater;
} else {
return Ordering::Less;
}
}
todo!();
}
}
impl Add for Bigint {
type Output = Bigint;
/// За да съберете две числа, първия въпрос е: какви са им знаците?
///
/// - Ако и двете са положителни, събираме ги цифра по цифра и слагаме на резултата положителен
/// знак.
/// - Ако и двете са отрицателни, пак можем да ги съберем цифра по цифра и да сложим
/// отрицателен знак на крайния резултат.
/// - Ако имат различни знаци, намираме по-голямото *по абсолютна стойност*. Изваждаме цифрите
/// на по-малкото от по-голямото. Знака на резултата е знака на по-голямото по абсолютна
/// стойност. Ако са равни, резултата трябва да е нула (която винаги се очаква да е
/// положителна).
///
/// При събиране цифра по цифра, не забравяйте да пренасяте "едно наум" ако резултата е
/// по-голям от десетична цифра. При различна дължина на списъците от цифри, можете да
/// запълните с нули, да внимавате с индексите, или нещо по средата.
///
fn add(self, other: Self) -> Self {
let mut result: Vec<u8> = Vec::new();
let sign: i8;
let mut vec1 = self.digits;
let mut vec2 = other.digits;
vec1.reverse();
vec2.reverse();
if vec1.len() >= vec2.len() {
vec2.extend(vec![0; vec1.len() - vec2.len()]);
} else {
vec1.extend(vec![0; vec2.len() - vec1.len()]);
}
let mut has_plus_one = false;
if self.sign == other.sign {
sign = self.sign;
for (index, num) in vec1.iter().enumerate() {
let mut sum = num + vec2[index];
if has_plus_one {
sum = sum + 1;
has_plus_one = false;
}
if sum > 9 {
sum = sum - 10;
has_plus_one = true;
}
result.push(sum);
}
if has_plus_one {
result.push(1);
}
} else {
// no time
sign = 1;
}
return Bigint::from_components(result, sign);
}
}
impl Sub for Bigint {
type Output = Bigint;
/// Изваждането често се имплементира като събиране с отрицателен знак. Тоест, `A - B` е
/// еквивалентно на `A + (-B)`. Можете да имплементирате изваждането като форма на събиране, и
/// в него да пакетирате логиката. Или можете да проверите знаците и да разделите логиката по
/// събиране и по изваждане между `add` и `sub`.
///
/// При изваждане, също не забравяйте "едното наум", ако цифрата от която вадите е по-малката,
/// което ще се преведе до едно "-1" на следващата цифра. Погрижете се винаги да вадите от
/// по-голямото по абсолютна стойност число, и после сложете какъвто знак се налага.
///
/// Внимавайте с типовете -- изваждане на unsigned от unsigned число може да се счупи.
///
fn sub(self, other: Self) -> Self {
self + Bigint::from_components(other.digits, other.sign * -1)
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20201127-2274206-va7bol/solution)
    Finished test [unoptimized + debuginfo] target(s) in 1.67s
     Running target/debug/deps/solution_test-589a43f0f4b10ca3

running 15 tests
test solution_test::test_bigint_construction ... ok
test solution_test::test_bigint_nonzero_sign ... ok
test solution_test::test_bigint_zero_sign ... ok
test solution_test::test_comparison ... FAILED
test solution_test::test_invalid_string ... ok
test solution_test::test_neutralization ... ok
test solution_test::test_parsing_with_and_without_sign ... ok
test solution_test::test_parsing_with_leading_zeroes ... ok
test solution_test::test_sub_1_basic ... FAILED
test solution_test::test_sub_2_diferent_lengths ... FAILED
test solution_test::test_sub_3_carry ... FAILED
test solution_test::test_sum_1_basic ... ok
test solution_test::test_sum_2_different_lengths ... FAILED
test solution_test::test_sum_3_overflow ... FAILED
test solution_test::test_sum_4_negative ... FAILED

failures:

---- solution_test::test_comparison stdout ----
thread 'main' panicked at 'not yet implemented', src/lib.rs:171:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- solution_test::test_sub_1_basic stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [0] }`,
 right: `Bigint { sign: 1, digits: [4, 4, 4] }`', tests/solution_test.rs:139:5

---- solution_test::test_sub_2_diferent_lengths stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [0] }`,
 right: `Bigint { sign: 1, digits: [1, 0, 0, 0] }`', tests/solution_test.rs:151:5

---- solution_test::test_sub_3_carry stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [0] }`,
 right: `Bigint { sign: 1, digits: [9, 9, 9] }`', tests/solution_test.rs:157:5

---- solution_test::test_sum_2_different_lengths stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [2, 1, 0, 2, 1] }`,
 right: `Bigint { sign: 1, digits: [1, 2, 0, 1, 2] }`', tests/solution_test.rs:88:5

---- solution_test::test_sum_3_overflow stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: 1, digits: [1] }`,
 right: `Bigint { sign: 1, digits: [1, 0, 0, 0] }`', tests/solution_test.rs:97:5

---- solution_test::test_sum_4_negative stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Bigint { sign: -1, digits: [9, 7, 5] }`,
 right: `Bigint { sign: -1, digits: [5, 7, 9] }`', tests/solution_test.rs:112:5


failures:
    solution_test::test_comparison
    solution_test::test_sub_1_basic
    solution_test::test_sub_2_diferent_lengths
    solution_test::test_sub_3_carry
    solution_test::test_sum_2_different_lengths
    solution_test::test_sum_3_overflow
    solution_test::test_sum_4_negative

test result: FAILED. 8 passed; 7 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--test solution_test'

История (3 версии и 0 коментара)

Борис качи първо решение на 27.11.2020 16:56 (преди почти 5 години)

Борис качи решение на 27.11.2020 16:58 (преди почти 5 години)

use std::cmp::Ordering;
use std::ops::{Add, Sub};
use std::str::FromStr;
#[derive(Debug)]
pub struct ParseError;
#[derive(Debug, PartialEq, Eq)]
pub struct Bigint {
sign: i8,
digits: Vec<u8>,
}
impl Bigint {
/// Конструира нов Bigint със стойност "0" и положителен знак.
/// Това може да означава празен вектор с цифри или масив с една цифра `0` -- ваш избор.
///
pub fn new() -> Self {
Bigint {
sign: 1,
digits: vec![0],
}
}
/// Конструира нов Bigint с подадените цифри и знак.
///
/// Тук е добро място където можете да вкарате малко валидация и нормализиране на входа -- да
/// премахнете допълнителни нули или да се погрижите, че нулата винаги има консистентен знак.
/// Стига да се погрижите винаги да използвате функцията при конструириане на нови Bigint-ове.
///
/// Тази функция НЕ Е публична, така че НЕ Е задължителна -- ако не ви трябва, може смело да я
/// изтриете.
///
pub fn from_components(digits: Vec<u8>, sign: i8) -> Self {
let mut new_sign: i8 = sign;
let mut new_digits = digits;
if sign != -1 && sign != 1 {
panic!("Sign can only be -1 or 1")
}
// if vector is empty make the element 0
if new_digits.len() < 1 {
new_digits = vec![0];
}
// zeroes are positive!
if new_digits == vec![0] {
new_sign = 1;
}
// remove starting zeros (ex. 000123 = 123)
loop {
if new_digits == vec![0] || new_digits[0] != 0 {
break;
}
new_digits.remove(0);
}
Bigint {
sign: new_sign,
digits: new_digits,
}
}
/// Връща `true` ако числото е положително. Нулата не е положителна.
pub fn is_positive(&self) -> bool {
self.sign == 1 && self.digits != vec![0]
}
/// Връща `true` ако числото е отрицателно. Нулата не е отрицателна.
pub fn is_negative(&self) -> bool {
self.sign == -1
}
}
impl FromStr for Bigint {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let sign: i8;
let mut digits: Vec<u8> = Vec::new();
match s.chars().nth(0) {
Some('+') => {
sign = 1;
// this should be in a function but no time :)
for (index, c) in s.chars().enumerate() {
if index != 0 {
if !c.is_digit(10) {
return Err(ParseError);
}
digits.push(c.to_digit(10).unwrap() as u8);
}
}
return Ok(Bigint::from_components(digits, sign));
}
Some('-') => {
sign = -1;
for (index, c) in s.chars().enumerate() {
if index != 0 {
if !c.is_digit(10) {
return Err(ParseError);
}
digits.push(c.to_digit(10).unwrap() as u8);
}
}
return Ok(Bigint::from_components(digits, sign));
}
_ => {
sign = 1;
for c in s.chars() {
if !c.is_digit(10) {
return Err(ParseError);
}
digits.push(c.to_digit(10).unwrap() as u8);
}
return Ok(Bigint::from_components(digits, sign));
}
};
}
}
impl PartialOrd for Bigint {
fn partial_cmp(&self, other: &Bigint) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Bigint {
/// Ако едното от числата има по-голям брой цифри, то ще бъде по-голямото. (Стига да не са нули
/// -- вероятно е добра идея да се погрижите да няма започващи нули при конструкция.)
///
/// Ако двете числа имат еднакъв брой цифри, лексикографско сравнение на числата ще ви даде
/// правилен резултат -- от по-значимите цифри към по-малко значимите. Внимавайте в какъв ред
/// си държите цифритe и дали не трябва да ги обърнете.
///
/// Ако двете числа са отрицателни, сравнението по абсолютна стойност ще е обърнато (-1 е
/// по-голямо от -2) -- погледнете документацията на `Ordering` за това как лесно можете да
/// обърнете резултата.
///
fn cmp(&self, other: &Bigint) -> Ordering {
if self.sign == other.sign {
if self.sign == 1 {
if self.digits.len() > other.digits.len() {
return Ordering::Greater;
} else if self.digits.len() < other.digits.len() {
return Ordering::Less;
} else {
for (i, num) in self.digits.iter().enumerate() {
if num != &other.digits[i] {
if num > &other.digits[i] {
return Ordering::Greater;
} else {
return Ordering::Less;
}
}
}
return Ordering::Equal;
}
}
} else {
if self.sign == 1 {
return Ordering::Greater;
} else {
return Ordering::Less;
}
}
todo!();
}
}
impl Add for Bigint {
type Output = Bigint;
/// За да съберете две числа, първия въпрос е: какви са им знаците?
///
/// - Ако и двете са положителни, събираме ги цифра по цифра и слагаме на резултата положителен
/// знак.
/// - Ако и двете са отрицателни, пак можем да ги съберем цифра по цифра и да сложим
/// отрицателен знак на крайния резултат.
/// - Ако имат различни знаци, намираме по-голямото *по абсолютна стойност*. Изваждаме цифрите
/// на по-малкото от по-голямото. Знака на резултата е знака на по-голямото по абсолютна
/// стойност. Ако са равни, резултата трябва да е нула (която винаги се очаква да е
/// положителна).
///
/// При събиране цифра по цифра, не забравяйте да пренасяте "едно наум" ако резултата е
/// по-голям от десетична цифра. При различна дължина на списъците от цифри, можете да
/// запълните с нули, да внимавате с индексите, или нещо по средата.
///
fn add(self, other: Self) -> Self {
let mut result: Vec<u8> = Vec::new();
let sign: i8;
let mut vec1 = self.digits;
let mut vec2 = other.digits;
vec1.reverse();
vec2.reverse();
if vec1.len() >= vec2.len() {
vec2.extend(vec![0; vec1.len() - vec2.len()]);
} else {
vec1.extend(vec![0; vec2.len() - vec1.len()]);
}
let mut has_plus_one = false;
if self.sign == other.sign {
sign = self.sign;
for (index, num) in vec1.iter().enumerate() {
let mut sum = num + vec2[index];
if has_plus_one {
sum = sum + 1;
has_plus_one = false;
}
if sum > 9 {
sum = sum - 10;
has_plus_one = true;
}
result.push(sum);
}
if has_plus_one {
result.push(1);
}
} else {
// no time
sign = 1;
}
return Bigint::from_components(result, sign);
}
}
+
+impl Sub for Bigint {
+ type Output = Bigint;
+
+ /// Изваждането често се имплементира като събиране с отрицателен знак. Тоест, `A - B` е
+ /// еквивалентно на `A + (-B)`. Можете да имплементирате изваждането като форма на събиране, и
+ /// в него да пакетирате логиката. Или можете да проверите знаците и да разделите логиката по
+ /// събиране и по изваждане между `add` и `sub`.
+ ///
+ /// При изваждане, също не забравяйте "едното наум", ако цифрата от която вадите е по-малката,
+ /// което ще се преведе до едно "-1" на следващата цифра. Погрижете се винаги да вадите от
+ /// по-голямото по абсолютна стойност число, и после сложете какъвто знак се налага.
+ ///
+ /// Внимавайте с типовете -- изваждане на unsigned от unsigned число може да се счупи.
+ ///
+ fn sub(self, other: Self) -> Self {
+ return self;
+ }
+}

Борис качи решение на 27.11.2020 16:58 (преди почти 5 години)

use std::cmp::Ordering;
use std::ops::{Add, Sub};
use std::str::FromStr;
#[derive(Debug)]
pub struct ParseError;
#[derive(Debug, PartialEq, Eq)]
pub struct Bigint {
sign: i8,
digits: Vec<u8>,
}
impl Bigint {
/// Конструира нов Bigint със стойност "0" и положителен знак.
/// Това може да означава празен вектор с цифри или масив с една цифра `0` -- ваш избор.
///
pub fn new() -> Self {
Bigint {
sign: 1,
digits: vec![0],
}
}
/// Конструира нов Bigint с подадените цифри и знак.
///
/// Тук е добро място където можете да вкарате малко валидация и нормализиране на входа -- да
/// премахнете допълнителни нули или да се погрижите, че нулата винаги има консистентен знак.
/// Стига да се погрижите винаги да използвате функцията при конструириане на нови Bigint-ове.
///
/// Тази функция НЕ Е публична, така че НЕ Е задължителна -- ако не ви трябва, може смело да я
/// изтриете.
///
pub fn from_components(digits: Vec<u8>, sign: i8) -> Self {
let mut new_sign: i8 = sign;
let mut new_digits = digits;
if sign != -1 && sign != 1 {
panic!("Sign can only be -1 or 1")
}
// if vector is empty make the element 0
if new_digits.len() < 1 {
new_digits = vec![0];
}
// zeroes are positive!
if new_digits == vec![0] {
new_sign = 1;
}
// remove starting zeros (ex. 000123 = 123)
loop {
if new_digits == vec![0] || new_digits[0] != 0 {
break;
}
new_digits.remove(0);
}
Bigint {
sign: new_sign,
digits: new_digits,
}
}
/// Връща `true` ако числото е положително. Нулата не е положителна.
pub fn is_positive(&self) -> bool {
self.sign == 1 && self.digits != vec![0]
}
/// Връща `true` ако числото е отрицателно. Нулата не е отрицателна.
pub fn is_negative(&self) -> bool {
self.sign == -1
}
}
impl FromStr for Bigint {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let sign: i8;
let mut digits: Vec<u8> = Vec::new();
match s.chars().nth(0) {
Some('+') => {
sign = 1;
// this should be in a function but no time :)
for (index, c) in s.chars().enumerate() {
if index != 0 {
if !c.is_digit(10) {
return Err(ParseError);
}
digits.push(c.to_digit(10).unwrap() as u8);
}
}
return Ok(Bigint::from_components(digits, sign));
}
Some('-') => {
sign = -1;
for (index, c) in s.chars().enumerate() {
if index != 0 {
if !c.is_digit(10) {
return Err(ParseError);
}
digits.push(c.to_digit(10).unwrap() as u8);
}
}
return Ok(Bigint::from_components(digits, sign));
}
_ => {
sign = 1;
for c in s.chars() {
if !c.is_digit(10) {
return Err(ParseError);
}
digits.push(c.to_digit(10).unwrap() as u8);
}
return Ok(Bigint::from_components(digits, sign));
}
};
}
}
impl PartialOrd for Bigint {
fn partial_cmp(&self, other: &Bigint) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Bigint {
/// Ако едното от числата има по-голям брой цифри, то ще бъде по-голямото. (Стига да не са нули
/// -- вероятно е добра идея да се погрижите да няма започващи нули при конструкция.)
///
/// Ако двете числа имат еднакъв брой цифри, лексикографско сравнение на числата ще ви даде
/// правилен резултат -- от по-значимите цифри към по-малко значимите. Внимавайте в какъв ред
/// си държите цифритe и дали не трябва да ги обърнете.
///
/// Ако двете числа са отрицателни, сравнението по абсолютна стойност ще е обърнато (-1 е
/// по-голямо от -2) -- погледнете документацията на `Ordering` за това как лесно можете да
/// обърнете резултата.
///
fn cmp(&self, other: &Bigint) -> Ordering {
if self.sign == other.sign {
if self.sign == 1 {
if self.digits.len() > other.digits.len() {
return Ordering::Greater;
} else if self.digits.len() < other.digits.len() {
return Ordering::Less;
} else {
for (i, num) in self.digits.iter().enumerate() {
if num != &other.digits[i] {
if num > &other.digits[i] {
return Ordering::Greater;
} else {
return Ordering::Less;
}
}
}
return Ordering::Equal;
}
}
} else {
if self.sign == 1 {
return Ordering::Greater;
} else {
return Ordering::Less;
}
}
todo!();
}
}
impl Add for Bigint {
type Output = Bigint;
/// За да съберете две числа, първия въпрос е: какви са им знаците?
///
/// - Ако и двете са положителни, събираме ги цифра по цифра и слагаме на резултата положителен
/// знак.
/// - Ако и двете са отрицателни, пак можем да ги съберем цифра по цифра и да сложим
/// отрицателен знак на крайния резултат.
/// - Ако имат различни знаци, намираме по-голямото *по абсолютна стойност*. Изваждаме цифрите
/// на по-малкото от по-голямото. Знака на резултата е знака на по-голямото по абсолютна
/// стойност. Ако са равни, резултата трябва да е нула (която винаги се очаква да е
/// положителна).
///
/// При събиране цифра по цифра, не забравяйте да пренасяте "едно наум" ако резултата е
/// по-голям от десетична цифра. При различна дължина на списъците от цифри, можете да
/// запълните с нули, да внимавате с индексите, или нещо по средата.
///
fn add(self, other: Self) -> Self {
let mut result: Vec<u8> = Vec::new();
let sign: i8;
let mut vec1 = self.digits;
let mut vec2 = other.digits;
vec1.reverse();
vec2.reverse();
if vec1.len() >= vec2.len() {
vec2.extend(vec![0; vec1.len() - vec2.len()]);
} else {
vec1.extend(vec![0; vec2.len() - vec1.len()]);
}
let mut has_plus_one = false;
if self.sign == other.sign {
sign = self.sign;
for (index, num) in vec1.iter().enumerate() {
let mut sum = num + vec2[index];
if has_plus_one {
sum = sum + 1;
has_plus_one = false;
}
if sum > 9 {
sum = sum - 10;
has_plus_one = true;
}
result.push(sum);
}
if has_plus_one {
result.push(1);
}
} else {
// no time
sign = 1;
}
return Bigint::from_components(result, sign);
}
}
impl Sub for Bigint {
type Output = Bigint;
/// Изваждането често се имплементира като събиране с отрицателен знак. Тоест, `A - B` е
/// еквивалентно на `A + (-B)`. Можете да имплементирате изваждането като форма на събиране, и
/// в него да пакетирате логиката. Или можете да проверите знаците и да разделите логиката по
/// събиране и по изваждане между `add` и `sub`.
///
/// При изваждане, също не забравяйте "едното наум", ако цифрата от която вадите е по-малката,
/// което ще се преведе до едно "-1" на следващата цифра. Погрижете се винаги да вадите от
/// по-голямото по абсолютна стойност число, и после сложете какъвто знак се налага.
///
/// Внимавайте с типовете -- изваждане на unsigned от unsigned число може да се счупи.
///
fn sub(self, other: Self) -> Self {
- return self;
+ self + Bigint::from_components(other.digits, other.sign * -1)
}
}