Allow big numbers as input, #130

This commit is contained in:
PaddiM8 2024-04-03 01:34:35 +02:00
parent 8ffc0e1e9d
commit f846a5b59e
5 changed files with 29 additions and 38 deletions

View File

@ -1,4 +1,4 @@
use crate::lexer::TokenKind;
use crate::{kalk_value::KalkFloat, lexer::TokenKind};
/// A tree structure of a statement.
#[derive(Debug, Clone, PartialEq)]
@ -19,10 +19,7 @@ pub enum Expr {
Var(Identifier),
Group(Box<Expr>),
FnCall(Identifier, Vec<Expr>),
#[cfg(feature="rug")]
Literal(rug::Float),
#[cfg(not(feature="rug"))]
Literal(f64),
Literal(KalkFloat),
Boolean(bool),
Piecewise(Vec<ConditionalPiece>),
Vector(Vec<Expr>),

View File

@ -2,6 +2,7 @@ use crate::ast::{Expr, Stmt};
use crate::ast::{Identifier, RangedVar};
use crate::calculation_result::CalculationResult;
use crate::errors::KalkError;
use crate::kalk_value::KalkFloat;
use crate::kalk_value::KalkValue;
use crate::lexer::TokenKind;
use crate::parser::DECL_UNIT;
@ -323,28 +324,20 @@ fn eval_var_expr(
}
#[allow(unused_variables)]
#[cfg(feature = "rug")]
fn eval_literal_expr(
context: &mut Context,
value: rug::Float,
value: KalkFloat,
unit: Option<&String>,
) -> Result<KalkValue, KalkError> {
#[allow(unused_mut)]
let mut float = float!(value);
#[cfg(feature = "rug")]
float.set_prec(context.precision);
Ok(KalkValue::Number(float, float!(0), unit.cloned()))
}
#[allow(unused_variables)]
#[cfg(not(feature = "rug"))]
fn eval_literal_expr(
context: &mut Context,
value: f64,
unit: Option<&String>,
) -> Result<KalkValue, KalkError> {
Ok(KalkValue::Number(float!(value), float!(0), unit.cloned()))
}
fn eval_group_expr(
context: &mut Context,
expr: &Expr,

View File

@ -18,6 +18,12 @@ use self::rounding::EstimationResult;
const ACCEPTABLE_COMPARISON_MARGIN: f64 = 0.00000001;
#[cfg(feature = "rug")]
pub(crate) type KalkFloat = rug::Float;
#[cfg(not(feature = "rug"))]
pub(crate) type KalkFloat = f64;
#[macro_export]
#[cfg(not(feature = "rug"))]
macro_rules! float {

View File

@ -4,6 +4,7 @@ use crate::analysis;
use crate::ast::Identifier;
use crate::calculation_result::CalculationResult;
use crate::errors::KalkError;
use crate::kalk_value::KalkFloat;
use crate::{
ast::{Expr, Stmt},
interpreter,
@ -770,8 +771,8 @@ fn skip_newlines(context: &mut Context) {
}
}
fn string_to_num(value: &str) -> Result<KalkFloat, KalkError> {
#[cfg(feature = "rug")]
fn string_to_num(value: &str) -> Result<rug::Float, KalkError> {
use rug::ops::Pow;
if value.contains('E') {
@ -779,24 +780,10 @@ fn string_to_num(value: &str) -> Result<rug::Float, KalkError> {
let left = crate::float!(string_to_num(parts[0])?);
let right = crate::float!(string_to_num(parts[1])?);
#[cfg(feature = "rug")]
return Ok(left * 10.pow(right));
}
let base = get_base(value)?;
if let Some(result) = crate::radix::parse_float_radix(&value.replace(' ', ""), base) {
Ok(crate::float!(result))
} else {
Err(KalkError::InvalidNumberLiteral(value.into()))
}
}
#[cfg(not(feature = "rug"))]
fn string_to_num(value: &str) -> Result<f64, KalkError> {
if value.contains('E') {
let parts = value.split('E').collect::<Vec<_>>();
let left = crate::float!(string_to_num(parts[0])?);
let right = crate::float!(string_to_num(parts[1])?);
return Ok(left * 10_f64.powf(right));
}

View File

@ -1,13 +1,21 @@
pub fn parse_float_radix(value: &str, radix: u8) -> Option<f64> {
use crate::{float, kalk_value::KalkFloat};
pub fn parse_float_radix(value: &str, radix: u8) -> Option<KalkFloat> {
if radix == 10 {
return if let Ok(result) = value.parse::<f64>() {
#[cfg(feature = "rug")]
let parsed = rug::Float::parse(value).map(|valid| crate::float!(valid));
#[cfg(not(feature = "rug"))]
let parsed = value.parse::<f64>();
return if let Ok(result) = parsed {
Some(result)
} else {
None
};
}
let mut sum = 0f64;
let mut sum = float!(0f64);
let length = value.find('_').unwrap_or(value.len());
let mut i = (value.find('.').unwrap_or(length) as i32) - 1;
for c in value.chars() {