Skip to content

Precision lost with double numbers #33

Description

@mingodad

When testing nullc with the tests from https://github.com/ArashPartow/exprtk there is a big difference in the total of equal expressions compared to C/C++ or other programming languages:

import std.io;
import std.math;

int total_count = 0;
int total_eq = 0;

void equal(double a, double b) {
	++total_count;
	if(a == b) {
		++total_eq;
	}
	//else { io.out << a << "<>" << b << io.endl;}
	else { io.out << total_count << "\t";Print(a, 16); io.out << "<>"; Print(b, 16); io.out << io.endl;}
}


double x, y, z, w;

x=11.12345678910737373;
y=22.12345678910737373;
z=33.12345678910737373;
w=44.12345678910737373;
//...
equal((-10.123456789107372000000000000000),(3-(2+abs(x))));
equal((-10.123456789107372000000000000000),(3-(abs(x)+2)));
io.out << "-10.123456789107372" << " == " << -10.123456789107372000000000000000 << " == "; Print(-10.123456789107372000000000000000, 16); io.out << io.endl;

io.out << total_count << "\t" << total_eq << io.endl;

return 0;

Output before :

-10.123456789107372 == -10.123456790947 == -10.1234567909470208
7366	417

Output after:

-10.123456789107372 == -10.123456789107 == -10.1234567891073723
7366	6923

Patch to get a better double precision and also accept numbers like .23, -.34, ...:

--------------------------- NULLC/ExpressionTree.cpp ---------------------------
index 40da9356..f6fd3dbc 100644
@@ -269,7 +269,7 @@ namespace
 	
 		if(*str == '.')
 		{
-			double power = 0.1f;
+			double power = 0.1;
 			str++;
 
 			while((digit = *str - '0') < 10)
@@ -280,7 +280,7 @@ namespace
 			}
 		}
 
-		if(*str == 'e')
+		if(*str == 'e' || *str == 'E')
 		{
 			str++;
 
@@ -3792,7 +3792,7 @@ ExprBase* AnalyzeNumber(ExpressionContext &ctx, SynNumber *syntax)
 
 	for(unsigned i = 0; i < value.length(); i++)
 	{
-		if(value.begin[i] == '.' || value.begin[i] == 'e')
+		if(value.begin[i] == '.' || value.begin[i] == 'e' || value.begin[i] == 'E')
 			isFP = true;
 	}
 

------------------------------- NULLC/Lexer.cpp -------------------------------
index 6ce9c8de..4fcd7649 100644
@@ -132,7 +132,8 @@ void Lexer::Lexify(const char* code)
 			}
 			break;
 		case '.':
-			lType = lex_point;
+                        if(isDigit(code[1])) goto do_lex_number;
+			else lType = lex_point;
 			break;
 		case ',':
 			lType = lex_comma;
@@ -392,6 +393,7 @@ void Lexer::Lexify(const char* code)
 		default:
 			if(isDigit(*code))
 			{
+do_lex_number:                    
 				lType = lex_number;
 
 				const char *pos = code;
@@ -408,7 +410,7 @@ void Lexer::Lexify(const char* code)
 					pos++;
 				while(isDigit(*pos))
 					pos++;
-				if(*pos == 'e')
+				if(*pos == 'e' || *pos == 'E')
 				{
 					pos++;
 					if(*pos == '-')

Full test source
exprtk_functional_test.nc.zip

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions