-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Describe the bug
When converting a negative integer to a floating point value, a Poco::RangeException is trown for values that do not lose precision when converted to float/double. This seems to be a bug in Dynamic/VarHolder.h::numValDigits, called from isPrecisionLost in the same file:
template <typename T, std::enable_if_t<std::is_integral_v<T>, bool> = true>
static constexpr int numValDigits(const T& value)
{
using U = std::make_unsigned_t<T>;
if (value == 0) return 0;
int digitCount = 0;
U locVal = value; // to prevent sign preservation
while (locVal >>= 1) ++digitCount;
return digitCount;
}
The line U locVal = value; // to prevent sign preservation
assigns the two's compliment value to locVal, and as such does not return the correct number of significant digits.
To Reproduce
#include "Poco/Dynamic/Var.h"
int main(void)
{
Poco::Dynamic::Var value = (int64_t)-10;
double answer = value.convert<double>();
return (0);
}
Running this code results in:
terminate called after throwing an instance of 'Poco::RangeException'
what(): Out of range
Expected behavior
The value stored in the Poco:Dynamic::Var should be converted to the equivalent double value if the original value fits within a double without precision loss and not throw an unnecessary exception. In the above example, -10 should be stored in the answer variable.
Logs
n/a
Screenshots
n/a
Please add relevant environment information:
- OS: Debian 12 (more specifically the vscode Debian c++ development container mcr.microsoft.com/vscode/devcontainers/cpp:1.2.7-debian-12)
- POCO Version: 1.14.1
Additional context
n/a
Metadata
Metadata
Assignees
Labels
Type
Projects
Status