Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Precision lost with double numbers #33

@mingodad

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

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