User-configurable precision

This commit is contained in:
PaddiM8 2020-12-13 18:12:33 +01:00
parent 0ce06d96b9
commit fbf901620f
4 changed files with 30 additions and 12 deletions

View File

@ -56,6 +56,10 @@ impl KalkNum {
}
}
pub fn to_string_big(&self) -> String {
self.value.to_string()
}
pub fn is_too_big(&self) -> bool {
self.value.is_infinite()
}

View File

@ -6,12 +6,15 @@ use std::env;
use std::fs::File;
use std::io::Read;
static DEFAULT_PRECISION: u32 = 53;
fn main() {
let mut parser_context = parser::Context::new().set_angle_unit(&get_angle_unit());
// Command line argument input, execute it and exit.
let mut args = env::args().skip(1);
let mut expr_input: Option<String> = None;
let mut precision = DEFAULT_PRECISION;
loop {
// Get the next argument if possible, otherwise break the loop.
let arg = if let Some(arg) = args.next() {
@ -28,8 +31,9 @@ fn main() {
[kalk help]
kalk [OPTIONS] [INPUT]
-h, --help : show this
-i : load a file with predefined functions/variables
-h, --help : show this
-i : load a file with predefined functions/variables
--precision : specify number precision
[Environment variables]
ANGLE_UNIT=(deg/rad) : Sets the default unit used for trigonometric functions.
@ -47,9 +51,16 @@ ANGLE_UNIT=(deg/rad) : Sets the default unit used for trigonometric functions.
// Parse the input file content, resulting in the symbol table being filled out.
// Output is not needed here.
parser::eval(&mut parser_context, &file_content, 53)
parser::eval(&mut parser_context, &file_content, precision)
.expect("Failed to parse input file.");
}
"--precision" => {
precision = args
.next()
.expect("Expected precision input.")
.parse::<u32>()
.expect("Precision value could not be parsed.");
}
_ => {
// Main argument. This is expected to be a maths expression.
// After the loop is finished, this will be parsed and outputted.
@ -60,10 +71,10 @@ ANGLE_UNIT=(deg/rad) : Sets the default unit used for trigonometric functions.
if let Some(input) = expr_input {
// Direct output
output::eval(&mut parser_context, &input);
output::eval(&mut parser_context, &input, precision);
} else {
// REPL
repl::start(&mut parser_context);
repl::start(&mut parser_context, precision);
}
}

View File

@ -1,14 +1,17 @@
use crate::DEFAULT_PRECISION;
use ansi_term::Colour::Red;
use kalk::parser::{self, CalcError, CalcError::*};
pub fn eval(parser: &mut parser::Context, input: &str) {
match parser::eval(parser, input, 53) {
pub fn eval(parser: &mut parser::Context, input: &str, precision: u32) {
match parser::eval(parser, input, precision) {
Ok(Some(result)) => {
let sci_notation = result.to_scientific_notation();
let result_str = if sci_notation.exponent > 8 || sci_notation.exponent < -6 {
sci_notation.to_string()
} else {
} else if precision == DEFAULT_PRECISION {
result.to_string()
} else {
result.to_string_big()
};
println!("{} {}", result_str, result.get_unit());

View File

@ -18,7 +18,7 @@ use std::borrow::Cow::Owned;
use std::collections::HashMap;
use std::process;
pub fn start(mut parser: &mut parser::Context) {
pub fn start(mut parser: &mut parser::Context, precision: u32) {
let mut editor = Editor::<RLHelper>::new();
editor.set_helper(Some(RLHelper {
highlighter: LineHighlighter {},
@ -36,7 +36,7 @@ pub fn start(mut parser: &mut parser::Context) {
match readline {
Ok(input) => {
editor.add_history_entry(input.as_str());
eval_repl(&mut parser, &input);
eval_repl(&mut parser, &input, precision);
}
Err(ReadlineError::Interrupted) => break,
_ => break,
@ -44,12 +44,12 @@ pub fn start(mut parser: &mut parser::Context) {
}
}
fn eval_repl(parser: &mut parser::Context, input: &str) {
fn eval_repl(parser: &mut parser::Context, input: &str, precision: u32) {
match input {
"" => eprint!(""),
"clear" => print!("\x1B[2J"),
"exit" => process::exit(0),
_ => output::eval(parser, input),
_ => output::eval(parser, input, precision),
}
}