Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expressions with big Integers evaluate either to wrongs results or they throw a System.OverflowException #38

Open
XN01404 opened this issue Nov 14, 2019 · 1 comment

Comments

@XN01404
Copy link

XN01404 commented Nov 14, 2019

  1. In the first example the results a supposed to be the same, but expression2 evaluates to : -3478141659,48 instead of 816825636.52
    <TestMethod()>
    Public Sub TestNCalc()

        Dim expression1 As String = "(-1413174363.48)+200000000+2030000000"
        Dim expression2 As String = "200000000+2030000000-1413174363.48"

        Dim exp1 As Func(Of Decimal) = New Expression(expression1).ToLambda(Of Decimal)
        Dim exp2 As Func(Of Decimal) = New Expression(expression2).ToLambda(Of Decimal)

        Dim calculatedValue1 As Decimal = exp1()
        Dim calculatedValue2 As Decimal = exp2()

        Assert.AreEqual(816825636.52D, exp1())
        Assert.AreEqual(816825636.52D, exp2())

    End Sub
  1. The second example does not work at all. Here as System.OverflowException is thrown.
    <TestMethod()>
    Public Sub TestNCalc1()

        Dim expression As String = "if(2080000000>2200321782,0,2200321782-2080000000)"
        Dim calculatedValue As Decimal = New Expression(expression).Evaluate()

        Assert.AreEqual(120321782, calculatedValue)

    End Sub

==========

I am using the latest version of NCoreCalc 2.2.70.

@XN01404
Copy link
Author

XN01404 commented Nov 15, 2019

I debugged your Code and I found an easy solution:

if you change

public ValueExpression(int value) to public ValueExpression(long value)

it works perfectly fine.

using System;
using System.Reflection;

namespace NCalc.Domain
{
	public class ValueExpression : LogicalExpression
	{
        public ValueExpression(object value, ValueType type)
        {
            Value = value;
            Type = type;
        }

        public ValueExpression(object value)
        {
            switch (value.GetTypeCode())
            {
                case TypeCode.Boolean :
                    Type = ValueType.Boolean;
                    break;

                case TypeCode.DateTime :
                    Type = ValueType.DateTime;
                    break;

                case TypeCode.Decimal:
                case TypeCode.Double:
                case TypeCode.Single:
                    Type = ValueType.Float;
                    break;

                case TypeCode.Byte:
                case TypeCode.SByte:
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                    Type = ValueType.Integer;
                    break;

                case TypeCode.String:
                    Type = ValueType.String;
                    break;

                default:
                    throw new EvaluationException("This value could not be handled: " + value);
            }

            Value = value;
        }

        public ValueExpression(string value)
        {
            Value = value;
            Type = ValueType.String;
        }

        public ValueExpression(long value)
        {
            Value = value;
            Type = ValueType.Integer;
        }

        public ValueExpression(float value)
        {
            Value = value;
            Type = ValueType.Float;
        }

        public ValueExpression(DateTime value)
        {
            Value = value;
            Type = ValueType.DateTime;
        }

        public ValueExpression(bool value)
        {
            Value = value;
            Type = ValueType.Boolean;
        }

        public object Value { get; set; }
        public ValueType Type { get; set; }

        public override void Accept(LogicalExpressionVisitor visitor)
        {
            visitor.Visit(this);
        }
    }

	public enum ValueType
	{
		Integer,
		String,
		DateTime,
		Float,
		Boolean
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant