[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:
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user