Description of problem: running test (make check) of cxxtools package on ppc64le arch, I get an error on test:xmlserializer::testDouble problem occurs at testDoubleValue(std::numeric_limits<double>::max()); value returned is 1.79769e+308 and later in the test following exception is raised: EXCEPTION: value 1.79769e+308 does not fit into double Version-Release number of selected component (if applicable): cxxtools-2.2.1-4.fc21 ppc64le gcc-4.9.0-6.fc21 ppc64le Actual results: xmlserializer::testDouble: EXCEPTION value 1.79769e+308 does not fit into double
Back to this problem, I understood value 1.79769e+308 is correct for the maximum value of a type double. This means the problem is not relative to gcc. I change component to cxxtools for now.
Hi, here is the answer from the cxxtools forum http://sourceforge.net/p/tntnet/mailman/message/32573866/ Hi, The problem is a rounding error when converting double to decimal and back. The xmlserializer do not use scientific notation but converts floating point values to decimal, so that the maximum double value results in something like "17976900000000000000000000000000000000000000.....". Internally long double is used in serialization and due to rounding errors it may really happen, that the max double converted to long double converted to a string and back to double max do exceed the range. The solution may be to accept slightly larger values than max-double. The actual code, which results in the error can be found in include/cxxtools/serializationinfo.h and src/serializationinfo.cpp: serializationinfo.h: void getValue(double& value) const { value = static_cast<double>(_getFloat("double", std::numeric_limits<double>::max())); } serializationinfo.cpp: long double SerializationInfo::_getFloat(const char* type, long double max) const { ... if (ret != std::numeric_limits<long double>::infinity() && ret != -std::numeric_limits<long double>::infinity() && ret == ret // check for NaN && (ret < -max || ret > max)) { std::ostringstream msg; msg << "value " << ret << " does not fit into " << type; throw std::range_error(msg.str()); } A possible fix is to change the acceptable limits of double to a slightly larger value: serializationinfo.h: void getValue(double& value) const { value = static_cast<double>(_getFloat("double", static_cast<long double>(std::numeric_limits<double>::max()))*1.0000000001); } The same should be done with float type. What do you think? Question: what happens, when a long double value is really too large and it is casted to double? Tommi
(In reply to Menanteau Guy from comment #1) > Back to this problem, I understood value 1.79769e+308 is correct for the > maximum value of a type double. This means the problem is not relative to > gcc. I change component to cxxtools for now. can you provide a patch ?
Back to this problem. I understood the problem of rounding error due to diffrent precision between float and double but I don't see why not just process double as double instead of float. I did a patch to handle serialization double as double for casting and test is succesfull now. Note that there was no need to create a new t_double type in serializationinfo.h. Please could you have a look to the attached patch.
Created attachment 920168 [details] handle double as double an not float
answer pasted from forum http://sourceforge.net/p/tntnet/mailman/message/32648854/ Re: [Tntnet-general] cxxtools-2.2.1-4.fc21 ppc64le - std::numeric_limits<double>::max() returns 1.79769e+308 From: Tommi Mäkitalo <tommi@tn...> - 2014-07-25 18:14:35 Hi, I looked at the patch and I guess it does not solve the problem. The double value is still converted to long double, then to decimal and back to long double. Somewhere in this chain a rounding error increases the value slightly, that it is too large to fit into a double. The solution is to accept a slightly larger value than double max. If the value is just slightly bigger, it should be converted to double max. Tommi
ok let's have a look to this new patch. Thanks
Created attachment 921759 [details] New patch to accept slightly larger value than double max
answer from the developer http://sourceforge.net/p/tntnet/mailman/message/32657385/ Hi, I checked in a different solution. Your solution do not work correctly when using long double. Note that the max value in SerializationInfo::_getFloat may be std::numeric_limits<long double>::max, which should not be multiplied with a number larger than 1. So I changed the limit values passed to _getFloat when extracting float or double values. Tommi
Hi there, any luck to have a new version available with your correction ?
problem mybe solved in the meantime look at https://github.com/maekitalo/cxxtools/blob/master/ChangeLog