diff --git a/src/xml/xml_util.cc b/src/xml/xml_util.cc index 0d1a7f75..d7a09afc 100644 --- a/src/xml/xml_util.cc +++ b/src/xml/xml_util.cc @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -1004,7 +1005,8 @@ void mjXUtil::WriteAttr(XMLElement* elem, string name, int n, const T* data, con } // append number - if (isint(data[i])) { + double doubledata = static_cast(data[i]); + if (doubledata < INT_MAX && doubledata > -INT_MAX && isint(data[i])) { stream << Round(data[i]); } else { stream << data[i]; diff --git a/test/xml/xml_native_writer_test.cc b/test/xml/xml_native_writer_test.cc index f5989279..4b5b7f9e 100644 --- a/test/xml/xml_native_writer_test.cc +++ b/test/xml/xml_native_writer_test.cc @@ -1178,5 +1178,29 @@ TEST_F(DecompilerTest, DoesntSaveInferredStatitics) { mj_deleteModel(model); } +TEST_F(DecompilerTest, VeryLargeNumbers) { + static constexpr char xml[] = R"( + + + + + + + + + + + )"; + std::array error; + mjModel* model = LoadModelFromString(xml, error.data(), error.size()); + ASSERT_THAT(model, NotNull()) << error.data(); + std::string saved_xml = SaveAndReadXml(model); + // note, focal is float and loses precision 16777217 -> 16777216 + EXPECT_THAT(saved_xml, HasSubstr("focal=\"16777216 1\"")); + EXPECT_THAT(saved_xml, HasSubstr("pos=\"1e+20 0 0\"")); + EXPECT_THAT(saved_xml, HasSubstr("range=\"-1e+10 1e+10\"")); + mj_deleteModel(model); +} + } // namespace } // namespace mujoco