diff --git a/src/pugixml.cpp b/src/pugixml.cpp index af33ef8..aa8296e 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -4665,19 +4665,19 @@ PUGI__NS_BEGIN } template - PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, float value) + PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, float value, int precision) { char buf[128]; - PUGI__SNPRINTF(buf, "%.9g", double(value)); + PUGI__SNPRINTF(buf, "%.*g", precision, double(value)); return set_value_ascii(dest, header, header_mask, buf); } template - PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, double value) + PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, double value, int precision) { char buf[128]; - PUGI__SNPRINTF(buf, "%.17g", value); + PUGI__SNPRINTF(buf, "%.*g", precision, value); return set_value_ascii(dest, header, header_mask, buf); } @@ -5338,18 +5338,18 @@ namespace pugi return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false); } - PUGI__FN bool xml_attribute::set_value(double rhs) + PUGI__FN bool xml_attribute::set_value(double rhs, int precision) { if (!_attr) return false; - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, precision); } - PUGI__FN bool xml_attribute::set_value(float rhs) + PUGI__FN bool xml_attribute::set_value(float rhs, int precision) { if (!_attr) return false; - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, precision); } PUGI__FN bool xml_attribute::set_value(bool rhs) @@ -6062,7 +6062,7 @@ namespace pugi PUGI__FN bool xml_node::remove_attributes() { if (!_root) return false; - + impl::xml_allocator& alloc = impl::get_allocator(_root); if (!alloc.reserve()) return false; @@ -6545,14 +6545,14 @@ namespace pugi { xml_node_struct* dn = _data_new(); - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, default_float_precision) : false; } PUGI__FN bool xml_text::set(double rhs) { xml_node_struct* dn = _data_new(); - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, default_double_precision) : false; } PUGI__FN bool xml_text::set(bool rhs) diff --git a/src/pugixml.hpp b/src/pugixml.hpp index 8986d2a..0226524 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -263,6 +263,9 @@ namespace pugi // Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none. const unsigned int format_default = format_indent; + const unsigned int default_double_precision = 17; + const unsigned int default_float_precision = 9; + // Forward declarations struct xml_attribute_struct; struct xml_node_struct; @@ -409,8 +412,8 @@ namespace pugi bool set_value(unsigned int rhs); bool set_value(long rhs); bool set_value(unsigned long rhs); - bool set_value(double rhs); - bool set_value(float rhs); + bool set_value(double rhs, int precision=default_double_precision); + bool set_value(float rhs, int precision=default_float_precision); bool set_value(bool rhs); #ifdef PUGIXML_HAS_LONG_LONG diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp index 319555a..ebeabe1 100644 --- a/tests/test_dom_modify.cpp +++ b/tests/test_dom_modify.cpp @@ -1762,6 +1762,19 @@ TEST(dom_fp_roundtrip_min_max_double) CHECK(fp_equal(node.text().as_double(), std::numeric_limits::max())); } +TEST(dom_fp_double_custom_precision) +{ + xml_document doc; + xml_node node = doc.append_child(STR("node")); + xml_attribute attr = node.append_attribute(STR("attr")); + + attr.set_value(std::numeric_limits::min(), 20); + CHECK(fp_equal(attr.as_double(), std::numeric_limits::min())); + + node.text().set(std::numeric_limits::max()); + CHECK(fp_equal(node.text().as_double(), std::numeric_limits::max())); +} + const double fp_roundtrip_base[] = { 0.31830988618379067154,