implement a fix to floating point precision as proposed by schuellc.

This commit is contained in:
Lee Thomason 2014-01-14 12:30:03 -08:00
parent 61871d60a6
commit c3708ccf08
5 changed files with 80 additions and 43 deletions

View File

@ -10,8 +10,8 @@ include(GNUInstallDirs)
################################ ################################
# set lib version here # set lib version here
set(GENERIC_LIB_VERSION "1.0.12") set(GENERIC_LIB_VERSION "1.0.13")
set(GENERIC_LIB_SOVERSION "1") set(GENERIC_LIB_SOVERSION "1")
################################ ################################

2
dox
View File

@ -32,7 +32,7 @@ PROJECT_NAME = "TinyXML-2"
# This could be handy for archiving the generated documentation or # This could be handy for archiving the generated documentation or
# if some version control system is used. # if some version control system is used.
PROJECT_NUMBER = 1.0.12 PROJECT_NUMBER = 1.0.13
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer # for a project that appears at the top of each page and should give viewer

View File

@ -422,16 +422,19 @@ void XMLUtil::ToStr( bool v, char* buffer, int bufferSize )
TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 ); TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 );
} }
/*
ToStr() of a number is a very tricky topic.
https://github.com/leethomason/tinyxml2/issues/106
*/
void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) void XMLUtil::ToStr( float v, char* buffer, int bufferSize )
{ {
TIXML_SNPRINTF( buffer, bufferSize, "%f", v ); TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v );
} }
void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) void XMLUtil::ToStr( double v, char* buffer, int bufferSize )
{ {
TIXML_SNPRINTF( buffer, bufferSize, "%f", v ); TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v );
} }
@ -497,12 +500,7 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
} }
// What is this thing? // What is this thing?
// - Elements start with a letter or underscore, but xml is reserved. // These strings define the matching patters:
// - Comments: <!--
// - Declaration: <?
// - Everything else is unknown to tinyxml.
//
static const char* xmlHeader = { "<?" }; static const char* xmlHeader = { "<?" };
static const char* commentHeader = { "<!--" }; static const char* commentHeader = { "<!--" };
static const char* dtdHeader = { "<!" }; static const char* dtdHeader = { "<!" };

View File

@ -116,9 +116,9 @@ inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
#define TIXML_SSCANF sscanf #define TIXML_SSCANF sscanf
#endif #endif
static const int TIXML2_MAJOR_VERSION = 1; static const int TIXML2_MAJOR_VERSION = 1;
static const int TIXML2_MINOR_VERSION = 0; static const int TIXML2_MINOR_VERSION = 0;
static const int TIXML2_PATCH_VERSION = 12; static const int TIXML2_PATCH_VERSION = 13;
namespace tinyxml2 namespace tinyxml2
{ {
@ -1321,6 +1321,11 @@ public:
XMLAttribute* a = FindOrCreateAttribute( name ); XMLAttribute* a = FindOrCreateAttribute( name );
a->SetAttribute( value ); a->SetAttribute( value );
} }
/// Sets the named attribute to value.
void SetAttribute( const char* name, float value ) {
XMLAttribute* a = FindOrCreateAttribute( name );
a->SetAttribute( value );
}
/** /**
Delete an attribute. Delete an attribute.

View File

@ -1139,18 +1139,6 @@ int main( int argc, const char ** argv )
XMLTest( "Whitespace all space", true, 0 == doc.FirstChildElement()->FirstChild() ); XMLTest( "Whitespace all space", true, 0 == doc.FirstChildElement()->FirstChild() );
} }
#if 0 // the question being explored is what kind of print to use:
// https://github.com/leethomason/tinyxml2/issues/63
{
const char* xml = "<element attrA='123456789.123456789' attrB='1.001e9'/>";
XMLDocument doc;
doc.Parse( xml );
doc.FirstChildElement()->SetAttribute( "attrA", 123456789.123456789 );
doc.FirstChildElement()->SetAttribute( "attrB", 1.001e9 );
doc.Print();
}
#endif
{ {
// An assert should not fire. // An assert should not fire.
const char* xml = "<element/>"; const char* xml = "<element/>";
@ -1240,39 +1228,85 @@ int main( int argc, const char ** argv )
"</root>"; "</root>";
XMLDocument doc; XMLDocument doc;
doc.Parse( xml ); doc.Parse(xml);
XMLElement* subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree"); XMLElement* subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
XMLElement* two = doc.RootElement()->FirstChildElement("two"); XMLElement* two = doc.RootElement()->FirstChildElement("two");
two->InsertFirstChild(subtree); two->InsertFirstChild(subtree);
XMLPrinter printer1( 0, true ); XMLPrinter printer1(0, true);
doc.Accept( &printer1 ); doc.Accept(&printer1);
XMLTest( "Move node from within <one> to <two>", xmlInsideTwo, printer1.CStr()); XMLTest("Move node from within <one> to <two>", xmlInsideTwo, printer1.CStr());
doc.Parse( xml ); doc.Parse(xml);
subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree"); subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
two = doc.RootElement()->FirstChildElement("two"); two = doc.RootElement()->FirstChildElement("two");
doc.RootElement()->InsertAfterChild(two, subtree); doc.RootElement()->InsertAfterChild(two, subtree);
XMLPrinter printer2( 0, true ); XMLPrinter printer2(0, true);
doc.Accept( &printer2 ); doc.Accept(&printer2);
XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer2.CStr(), false ); XMLTest("Move node from within <one> after <two>", xmlAfterTwo, printer2.CStr(), false);
doc.Parse( xml ); doc.Parse(xml);
XMLNode* one = doc.RootElement()->FirstChildElement("one"); XMLNode* one = doc.RootElement()->FirstChildElement("one");
subtree = one->FirstChildElement("subtree"); subtree = one->FirstChildElement("subtree");
doc.RootElement()->InsertAfterChild(one, subtree); doc.RootElement()->InsertAfterChild(one, subtree);
XMLPrinter printer3( 0, true ); XMLPrinter printer3(0, true);
doc.Accept( &printer3 ); doc.Accept(&printer3);
XMLTest( "Move node from within <one> after <one>", xmlAfterOne, printer3.CStr(), false ); XMLTest("Move node from within <one> after <one>", xmlAfterOne, printer3.CStr(), false);
doc.Parse( xml ); doc.Parse(xml);
subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree"); subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
two = doc.RootElement()->FirstChildElement("two"); two = doc.RootElement()->FirstChildElement("two");
doc.RootElement()->InsertEndChild(subtree); doc.RootElement()->InsertEndChild(subtree);
XMLPrinter printer4( 0, true ); XMLPrinter printer4(0, true);
doc.Accept( &printer4 ); doc.Accept(&printer4);
XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr(), false ); XMLTest("Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr(), false);
} }
{
const char* xml = "<svg width = \"128\" height = \"128\">"
" <text> </text>"
"</svg>";
XMLDocument doc;
doc.Parse(xml);
doc.Print();
}
#if 1
// the question being explored is what kind of print to use:
// https://github.com/leethomason/tinyxml2/issues/63
{
//const char* xml = "<element attrA='123456789.123456789' attrB='1.001e9' attrC='1.0e-10' attrD='1001000000.000000' attrE='0.1234567890123456789'/>";
const char* xml = "<element/>";
XMLDocument doc;
doc.Parse( xml );
doc.FirstChildElement()->SetAttribute( "attrA-f64", 123456789.123456789 );
doc.FirstChildElement()->SetAttribute( "attrB-f64", 1.001e9 );
doc.FirstChildElement()->SetAttribute( "attrC-f64", 1.0e9 );
doc.FirstChildElement()->SetAttribute( "attrC-f64", 1.0e20 );
doc.FirstChildElement()->SetAttribute( "attrD-f64", 1.0e-10 );
doc.FirstChildElement()->SetAttribute( "attrD-f64", 0.123456789 );
doc.FirstChildElement()->SetAttribute( "attrA-f32", 123456789.123456789f );
doc.FirstChildElement()->SetAttribute( "attrB-f32", 1.001e9f );
doc.FirstChildElement()->SetAttribute( "attrC-f32", 1.0e9f );
doc.FirstChildElement()->SetAttribute( "attrC-f32", 1.0e20f );
doc.FirstChildElement()->SetAttribute( "attrD-f32", 1.0e-10f );
doc.FirstChildElement()->SetAttribute( "attrD-f32", 0.123456789f );
doc.Print();
/* The result of this test is platform, compiler, and library version dependent. :("
XMLPrinter printer;
doc.Print( &printer );
XMLTest( "Float and double formatting.",
"<element attrA-f64=\"123456789.12345679\" attrB-f64=\"1001000000\" attrC-f64=\"1e+20\" attrD-f64=\"0.123456789\" attrA-f32=\"1.2345679e+08\" attrB-f32=\"1.001e+09\" attrC-f32=\"1e+20\" attrD-f32=\"0.12345679\"/>\n",
printer.CStr(),
true );
*/
}
#endif
// ----------- Performance tracking -------------- // ----------- Performance tracking --------------
{ {
#if defined( _MSC_VER ) #if defined( _MSC_VER )