[types] Apply Safe::abs() in floatToRationalCast & gcd

Also check for infinity in floatToRationalCast as depending on the
compiler special values of floats are converted to either
LONGMAX/LONGMIN or +/-inf
This commit is contained in:
Dan Čermák
2018-08-21 23:09:56 +02:00
parent 2dacb19933
commit 11df43be78
2 changed files with 17 additions and 5 deletions
+8 -2
View File
@@ -38,6 +38,7 @@
#include <string>
#include <vector>
#include <iosfwd>
#include <limits>
#include <utility>
#include <algorithm>
#include <sstream>
@@ -555,8 +556,13 @@ namespace Exiv2 {
#ifdef _MSC_VER
#pragma warning( disable : 4146 )
#endif
if (n < zero)
n = -n;
if (n < zero) {
if (n == std::numeric_limits<IntType>::min()) {
n = std::numeric_limits<IntType>::max();
} else {
n = -n;
}
}
if (m < zero)
m = -m;
#ifdef _MSC_VER
+9 -3
View File
@@ -29,6 +29,7 @@
#include "types.hpp"
#include "i18n.h" // for _exvGettext
#include "unused.h"
#include "safe_op.hpp"
// + standard includes
#ifdef EXV_UNICODE_PATH
@@ -46,6 +47,7 @@
#include <cassert>
#include <cstring>
#include <cmath>
#include <math.h>
// *****************************************************************************
namespace {
@@ -657,11 +659,15 @@ namespace Exiv2 {
Rational floatToRationalCast(float f)
{
if (isinf(f)) {
return Rational(f > 0 ? 1 : -1, 0);
}
// Beware: primitive conversion algorithm
int32_t den = 1000000;
if (std::labs(static_cast<long>(f)) > 2147) den = 10000;
if (std::labs(static_cast<long>(f)) > 214748) den = 100;
if (std::labs(static_cast<long>(f)) > 21474836) den = 1;
const long f_as_long = static_cast<long>(f);
if (Safe::abs(f_as_long) > 2147) den = 10000;
if (Safe::abs(f_as_long) > 214748) den = 100;
if (Safe::abs(f_as_long) > 21474836) den = 1;
const float rnd = f >= 0 ? 0.5f : -0.5f;
const int32_t nom = static_cast<int32_t>(f * den + rnd);
const int32_t g = gcd(nom, den);