Skip to content

Commit

Permalink
Merge pull request #2 from Starfunk/Update-0.2.0
Browse files Browse the repository at this point in the history
Update 0.2.0
  • Loading branch information
Starfunk authored Jun 26, 2018
2 parents 8fed89c + aa2268e commit d080166
Show file tree
Hide file tree
Showing 8 changed files with 934 additions and 231 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[package]
name = "largeint"
version = "0.1.0"
version = "0.2.0"
authors = ["Maximilian Kahn <[email protected]>"]
license = "MIT"
description = "A library that supports large integer arithmetic using LargeInt."
description = "A library that supports large integer arithmetic."
readme = "README.md"
documentation = "https://docs.rs/largeint"
repository = "https://github.com/Starfunk/largeint"
keywords = ["largeint", "large", "int","bigint","num"]
categories = ["no-std"]
keywords = ["largeint", "int", "large","integer"]
categories = ["no-std", "data-structures"]

[dependencies]
49 changes: 36 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# largeint
A library that implements the `LargeInt` type, used for working with arbitrarily large integers in Rust!
A library that supports large integer arithmetic.

## Getting Started
First, add largeint to your dependencies:
```toml
[dependencies]
largeint = "0.1.0"
largeint = "0.2.0"
```
Next, add this to the root of your crate to bring the contents of largeint into the scope of your project:
```rust
Expand All @@ -14,18 +14,24 @@ extern crate largeint;
use largeint::largeint::*;
```


You can then easily create many instances of `LargeInt`:
```rust
let largeint1 = new(String::from("999999999999999999999"), Sign::Positive);
let largeint2 = new(String::from("999999999999999999999"), Sign::Negative);
let largeint3 = new(String::from("0"), Sign::Unsigned);
```
An instance of `LargeInt` contains two fields, the scalar value of the integer stored as a `String` and the sign of the integer stored as the enum, `Sign`, which can be `Positive`, `Negative`, or `Unsigned` (note that `0` is the only integer that should be assigned `Unsigned`).
An instance of `LargeInt` contains two fields, the scalar value of the integer stored as a `String` and the sign of the integer stored as the enum, `Sign`, which can be `Positive`, `Negative`, or `Unsigned` (note that `0` is the only integer that should be assigned `Unsigned`).

Using `new` to create an instance of `LargeInt` is highly recommended as there are checks in place to ensure that the the instance of `LargeInt` will be created properly. For example, creating an instance of a `LargeInt` with a scalar value of `0` using `new` will automatically assign `Sign::Unsigned` to the sign of the LargeInt even if you enter another `Sign` variant.

Using `new()` to create an instance of `LargeInt` is highly recommmended as there are checks in place to ensure that the `LargeInt` will be created properly.
The purpose of this library is to provide an easy-to-use large integer implementation in Rust.
The ideal user is one that is looking to write small scale projects for personal use and does
not want to spend time a lot of time learning a complex crate such as num-bigint. For example,
this library would be ideal for one looking to solve [Project Euler Problem 13](https://projecteuler.net/problem=13).
However, the largeint library is not particularly efficient and therefore it is recommended to use
a crate like num-bigint for more serious projects.

Refer to the documentation for more details.
Let's see just how easy it is to start performing large integer arithmetic!

## An Example

Expand All @@ -46,21 +52,38 @@ fn main() {
// Subtracting two LargeInts.
let largeint1 = new(String::from("33901489213409093401849249010492000112"), Sign::Negative);
let largeint2 = new(String::from("100320394280329423048093284093240234809833999"), Sign::Negative);
let largeint3 = largeint1.subtract(&largeint2);
let largeint3 = largeint1.sub(&largeint2);
let largeint4 = new(String::from("100320360378840209638999882243991224317833887"), Sign::Positive);
assert_eq!(largeint3,largeint4);


// Multiplying two LargeInts.
let largeint1 = new(String::from("239014892134090934018492404920112"), Sign::Negative);
let largeint2 = new(String::from("820948948039443908494308943885"), Sign::Negative);
let largeint3 = largeint1.mul(&largeint2);
let largeint4 = new(String::from("196219024263243108752932957733805138559777844813650340515915120"), Sign::Positive);
assert_eq!(largeint3,largeint4);

// Dividing two LargeInts.
let largeint1 = new(String::from("33901489213409093401849249010492088384894374938712"), Sign::Positive);
let largeint2 = new(String::from("1003203942803294230480932840934343489333999"), Sign::Negative);
let largeint3 = largeint1.div(&largeint2);
let largeint4 = new(String::from("33793217"), Sign::Negative);
assert_eq!(largeint3,largeint4);

//The get_int() method returns the scalar value of the LargeInt as a String.
println!("The value of largeint1 is: {}", largeint1.get_int());

//The get_sign() method returns the Sign of the LargeInt as a String.
println!("The Sign of largeint1 is: {}", largeint1.get_sign());
println!("The Sign of largeint1 is: {}", largeint1.get_sign());
}

```
## Updates
Code Breaking Changes:
The subtraction method has been renamed `sub` from `subtraction`.

New Library Additions:
Multiplication, floor division - and remainder - have been added.

## License
This project is licensed under the MIT License - see [LICENSE.md](https://github.com/Starfunk/largeint/blob/master/LICENSE) for more details.

## Future Updates
Integer multiplication and division for `LargeInt` is currently being developed and should be released sometime in the next few weeks in the `"0.2.0"` update.
52 changes: 51 additions & 1 deletion src/addition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub fn addition(large1: &str, large2: &str) -> String {
let mut sum = vec![];
let mut counter: u8 = 0;
let mut input: u8;

if large1.len() >= large2.len() {
large3 = &large1;
large4 = &large2;
Expand Down Expand Up @@ -52,3 +52,53 @@ pub fn addition(large1: &str, large2: &str) -> String {
let digits = vec_to_str(&sum);
digits
}


pub fn addition_2(large1: Vec<u8>, large2: Vec<u8>) -> Vec<u8> {
let large3: &Vec<u8>;
let large4: &Vec<u8>;
let mut sum = vec![];
let mut counter: u8 = 0;
let mut input: u8;

if large1.len() >= large2.len() {
large3 = &large1;
large4 = &large2;
} else {
large3 = &large2;
large4 = &large1;
}
let len_1 = large3.len();
let len_2 = large4.len();
for i in 0..len_2 {
input = large3[len_1 - i - 1] + large4[len_2 - i - 1] + counter;
if input >= 10 {
input = input - 10;
sum.insert(0, input);
counter = 1;
} else {
sum.insert(0, input);
counter = 0;
}
}
if len_1 > len_2 {
for i in (0..len_1 - len_2).rev() {
input = large3[i] + counter;

if input == 10 {
sum.insert(0, 0);
counter = 1;
} else {
sum.insert(0, input);
counter = 0;
}
}
if counter == 1 {
sum.insert(0, 1)
}
}
if len_1 == len_2 && counter == 1 {
sum.insert(0, 1);
}
sum
}
155 changes: 155 additions & 0 deletions src/division.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
use largeint::*;
use multiplication::multiplication_1;

pub fn division(large1: &str, large2: &str) -> Vec<String> {
let mut divided = String::from("");
let mut remainder_largeint: LargeInt;
let mut remainder_str = String::from("");
let output_vec: Vec<String>;
let sign = Sign::Positive;
let large2 = new(String::from(large2), sign);
let large1_length = large1.len();
let mut large1_slice: &str;
let mut flag = true;
let mut counter = 0;
while flag == true {
for i in 1..large1_length + 1 {
large1_slice = &large1[0..i];
let large1_piece = new(String::from(large1_slice), sign);
if large1_piece.compare(&large2) == Compare::Smaller {
counter += 1;
continue
} else if large1_piece.compare(&large2) == Compare::Larger {
for i in 1..10 {
let index = i.to_string();
let index_str= to_vec(&index[..]);
let large2_vec = to_vec(&large2.digits);
let product = multiplication_1(&large2_vec, &index_str);
let product_vec = vec_to_str(&product);
let product_largeint = new(product_vec, sign);
if large1_piece.compare(&product_largeint) == Compare::Smaller {
let index1 = i - 1;
let index1_str = index1.to_string();
divided.push_str(&index1.to_string());
let index1_largeint = to_vec(&index1_str);
let product_2 = multiplication_1(&large2_vec, &index1_largeint);
let product_vec_2 = vec_to_str(&product_2);
let product_largeint_2 = new(product_vec_2, sign);
remainder_largeint = large1_piece.sub(&product_largeint_2);
remainder_str = remainder_largeint.digits;
flag = false;
break
} else if large1_piece.compare(&product_largeint) == Compare::Equal {
remainder_str = String::from("0");
divided.push_str(&index);
flag = false;
break
}
}
counter += 1;
} else if large1_piece.compare(&large2) == Compare::Equal {
remainder_str.push_str("0");
divided.push_str("1");
counter += 1;
flag = false;
}
break
}
}
if counter != large1_length {
for _ in counter..large1_length + 1 {
if counter == large1_length {
break
}
if remainder_str == String::from("0") && &large1[counter..counter+1] == "0" {
remainder_str = String::from("0");
divided.push_str("0");
counter += 1;
}
else if remainder_str == String::from("0") && &large1[counter..counter+1] != "0" {
remainder_str = large1[counter..counter+1].to_string();
let remainder_largeint = new(remainder_str.clone(), sign);
if remainder_largeint.compare(&large2) == Compare::Smaller {
divided.push_str("0");
} else if remainder_largeint.compare(&large2) == Compare::Larger {
let output_tuple = find_the_highest_divider(&remainder_str, &large2, &mut divided);
divided = output_tuple.0;
remainder_str = output_tuple.1;
} else {
remainder_str = String::from("0");
divided.push_str("0");
}
counter += 1;
} else {
remainder_str.push_str(&large1[counter..counter+1]);
let mut remainder_largeint = new(remainder_str.clone(), sign);
if remainder_largeint.compare(&large2) == Compare::Smaller {
divided.push_str("0");
} else if remainder_largeint.compare(&large2) == Compare::Larger {
let output_tuple = find_the_highest_divider(&remainder_str, &large2, &mut divided);
divided = output_tuple.0;
remainder_str = output_tuple.1;
} else {
remainder_str = String::from("0");
divided.push_str("1");
}
counter += 1;
}
}
}
output_vec = vec![divided, remainder_str];
output_vec
}

fn find_the_highest_divider(remainder: &String, large2: &LargeInt, divided: &mut String) -> (String, String) {
let mut remainder_str = String::from("0");
let sign = Sign::Positive;
let remainder_largeint = new(remainder.clone(), sign);
let large2_vec = to_vec(&large2.digits);
let remainder2_largeint: LargeInt;
let mut index: String;
let mut index_vec: Vec<u8>;
let mut product: Vec<u8>;
for i in 0..10 {
index = i.to_string();
index_vec = to_vec(&index[..]);
if i == 0 {
product = vec![0]
} else {
product = multiplication_1(&large2_vec, &index_vec);
}
let product_str = vec_to_str(&product);
let product_largeint = new(product_str, sign);
if remainder_largeint.compare(&product_largeint) == Compare::Smaller {
let index1 = i - 1;
let index1_vec: Vec<u8>;
let index1_str: String;
if index1 == 0 {
index1_str = String::from("0");
} else {
index1_str = index1.to_string();
}
index1_vec = to_vec(&index1_str[..]);
let product1 = multiplication_1(&large2_vec, &index1_vec);
let product1_str = vec_to_str(&product1 );
let product1_largeint = new(product1_str, sign);
divided.push_str(&index1.to_string());
remainder2_largeint = remainder_largeint.sub(&product1_largeint);
remainder_str = remainder2_largeint.digits;
break
} else if i == 9 {
divided.push_str(&index.to_string());
remainder2_largeint = remainder_largeint.sub(&product_largeint);
remainder_str = remainder2_largeint.digits;
break
}
else if remainder_largeint.compare(&product_largeint) == Compare::Equal {
divided.push_str(&index);
remainder_str = String::from("0");
break
} else {
remainder_str = String::from("0");
}
}
(divided.clone(), remainder_str)
}
Loading

0 comments on commit d080166

Please sign in to comment.