Skip to content

Commit 1953610

Browse files
Update main.rs
Fix bugs that crash when input decimal number.
1 parent 4dbeb6b commit 1953610

File tree

1 file changed

+146
-27
lines changed

1 file changed

+146
-27
lines changed

src/main.rs

Lines changed: 146 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::collections::HashMap;
88
use std::env;
99
use std::fs::File;
1010
use std::io::{self, Error, Read, Write};
11+
use std::ops::{Add, Div, Mul, Sub};
1112
use std::path::Path;
1213
use std::thread::{self, sleep};
1314
use std::time::{Duration, SystemTime, UNIX_EPOCH};
@@ -86,34 +87,59 @@ fn input(prompt: &str) -> String {
8687
result.trim().to_string()
8788
}
8889

90+
fn convert(number: f64) -> (isize, isize) {
91+
const MAX_DENOMINATOR: isize = 1_000_000;
92+
93+
if number == 0.0 {
94+
return (0, 1);
95+
}
96+
97+
let mut best_numerator = 0;
98+
let mut best_denominator = 1;
99+
let mut best_diff = f64::MAX;
100+
101+
for denominator in 1..=MAX_DENOMINATOR {
102+
let numerator = (number * denominator as f64).round() as isize;
103+
let fraction = numerator as f64 / denominator as f64;
104+
let diff = (number - fraction).abs();
105+
106+
if diff < best_diff {
107+
best_diff = diff;
108+
best_numerator = numerator;
109+
best_denominator = denominator;
110+
111+
if diff == 0.0 {
112+
break;
113+
}
114+
}
115+
}
116+
117+
(best_numerator, best_denominator)
118+
}
119+
89120
#[derive(Debug, Clone, Copy)]
90121
struct Fraction {
91-
numerator: i32,
92-
denominator: i32,
122+
numerator: isize,
123+
denominator: isize,
93124
}
94125

95126
impl Fraction {
96-
fn new(value: f64) -> Self {
127+
fn new(number: f64) -> Self {
128+
let result = convert(number);
97129
let mut frac = Fraction {
98-
numerator: value as i32,
99-
denominator: 1,
130+
numerator: result.0,
131+
denominator: result.1,
100132
};
101133

102-
let precision = 0.0001;
103-
while (frac.to_f64() - value).abs() > precision {
104-
frac.denominator *= 10;
105-
frac.numerator = (value * frac.denominator as f64) as i32;
106-
}
107-
108134
frac.simplify();
109135
frac
110136
}
111137

112138
fn from(value: String) -> Fraction {
113139
let value = value.split("/").collect::<Vec<&str>>();
114140
let mut fraction = Fraction {
115-
numerator: value.get(0).unwrap_or(&"0").parse::<i32>().unwrap_or(1),
116-
denominator: value.get(1).unwrap_or(&"1").parse::<i32>().unwrap_or(1),
141+
numerator: value.get(0).unwrap_or(&"0").parse::<isize>().unwrap_or(1),
142+
denominator: value.get(1).unwrap_or(&"1").parse::<isize>().unwrap_or(1),
117143
};
118144
fraction.simplify();
119145
fraction
@@ -131,7 +157,7 @@ impl Fraction {
131157
// Function to simplify the fraction
132158
fn simplify(&mut self) {
133159
// Function to find the greatest common divisor (GCD) using Euclid's algorithm
134-
fn gcd(mut a: i32, mut b: i32) -> i32 {
160+
fn gcd(mut a: isize, mut b: isize) -> isize {
135161
while b != 0 {
136162
let temp = b;
137163
b = a % b;
@@ -147,7 +173,94 @@ impl Fraction {
147173

148174
// Function to convert the fraction to a floating-point number
149175
fn to_f64(&self) -> f64 {
150-
self.numerator as f64 / self.denominator as f64
176+
(self.numerator / self.denominator) as f64
177+
}
178+
}
179+
180+
impl Add for Fraction {
181+
type Output = Fraction;
182+
183+
fn add(self, other: Fraction) -> Fraction {
184+
let number = other;
185+
fn lcm(a: isize, b: isize) -> isize {
186+
let gcd = |mut a: isize, mut b: isize| {
187+
while b != 0 {
188+
let temp = b;
189+
b = a % b;
190+
a = temp;
191+
}
192+
a
193+
};
194+
195+
(a * b) / gcd(a, b)
196+
}
197+
198+
let denominator = lcm(self.denominator, number.denominator);
199+
let numerator1 = self.numerator * (denominator / number.denominator);
200+
let numerator2 = number.numerator * (denominator / self.denominator);
201+
let mut result = Fraction {
202+
numerator: numerator1 + numerator2,
203+
denominator,
204+
};
205+
result.simplify();
206+
result
207+
}
208+
}
209+
210+
impl Sub for Fraction {
211+
type Output = Fraction;
212+
213+
fn sub(self, other: Fraction) -> Fraction {
214+
let number = other;
215+
fn lcm(a: isize, b: isize) -> isize {
216+
let gcd = |mut a: isize, mut b: isize| {
217+
while b != 0 {
218+
let temp = b;
219+
b = a % b;
220+
a = temp;
221+
}
222+
a
223+
};
224+
225+
(a * b) / gcd(a, b)
226+
}
227+
228+
let denominator = lcm(self.denominator, number.denominator);
229+
let numerator1 = self.numerator * (denominator / number.denominator);
230+
let numerator2 = number.numerator * (denominator / self.denominator);
231+
let mut result = Fraction {
232+
numerator: numerator1 - numerator2,
233+
denominator,
234+
};
235+
result.simplify();
236+
result
237+
}
238+
}
239+
240+
impl Mul for Fraction {
241+
type Output = Fraction;
242+
243+
fn mul(self, other: Fraction) -> Fraction {
244+
let number = other;
245+
let mut result = Fraction {
246+
numerator: self.numerator * number.numerator,
247+
denominator: self.denominator * number.denominator,
248+
};
249+
result.simplify();
250+
result
251+
}
252+
}
253+
254+
impl Div for Fraction {
255+
type Output = Fraction;
256+
257+
fn div(self, other: Fraction) -> Fraction {
258+
let mut number = other;
259+
(number.denominator, number.numerator) = (number.numerator, number.denominator);
260+
261+
let mut result = self * number;
262+
result.simplify();
263+
result
151264
}
152265
}
153266

@@ -574,30 +687,30 @@ impl Executor {
574687

575688
// Addition
576689
"add" => {
577-
let b = self.pop_stack().get_number().to_f64();
578-
let a = self.pop_stack().get_number().to_f64();
579-
self.stack.push(Type::Number(Fraction::new(a + b)));
690+
let b = self.pop_stack().get_number();
691+
let a = self.pop_stack().get_number();
692+
self.stack.push(Type::Number(a + b));
580693
}
581694

582695
// Subtraction
583696
"sub" => {
584-
let b = self.pop_stack().get_number().to_f64();
585-
let a = self.pop_stack().get_number().to_f64();
586-
self.stack.push(Type::Number(Fraction::new(a - b)));
697+
let b = self.pop_stack().get_number();
698+
let a = self.pop_stack().get_number();
699+
self.stack.push(Type::Number(a - b));
587700
}
588701

589702
// Multiplication
590703
"mul" => {
591-
let b = self.pop_stack().get_number().to_f64();
592-
let a = self.pop_stack().get_number().to_f64();
593-
self.stack.push(Type::Number(Fraction::new(a * b)));
704+
let b = self.pop_stack().get_number();
705+
let a = self.pop_stack().get_number();
706+
self.stack.push(Type::Number(a * b));
594707
}
595708

596709
// Division
597710
"div" => {
598-
let b = self.pop_stack().get_number().to_f64();
599-
let a = self.pop_stack().get_number().to_f64();
600-
self.stack.push(Type::Number(Fraction::new(a / b)));
711+
let b = self.pop_stack().get_number();
712+
let a = self.pop_stack().get_number();
713+
self.stack.push(Type::Number(a / b));
601714
}
602715

603716
// Remainder of division
@@ -638,6 +751,12 @@ impl Executor {
638751
self.stack.push(Type::Number(Fraction::new(number.tan())))
639752
}
640753

754+
// Exponential function
755+
"exp" => {
756+
let number = self.pop_stack().get_number().to_f64();
757+
self.stack.push(Type::Number(Fraction::new(number.exp())))
758+
}
759+
641760
// Logical operations of AND
642761
"and" => {
643762
let b = self.pop_stack().get_bool();

0 commit comments

Comments
 (0)