Skip to content

Commit

Permalink
Avoid UB in fastPow
Browse files Browse the repository at this point in the history
On GCC with -O1 or -O2 optimizations, this new implementation generates
identical assembly to the old union-based implementation
  • Loading branch information
messmerd committed Sep 25, 2024
1 parent e82932a commit a61a6ff
Showing 1 changed file with 11 additions and 9 deletions.
20 changes: 11 additions & 9 deletions include/lmms_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@

#include <QtGlobal>
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstring>

#include "lmms_constants.h"
#include "lmmsconfig.h"
#include <cassert>

namespace lmms
{
Expand Down Expand Up @@ -99,14 +100,15 @@ static void roundAt(T& value, const T& where, const T& stepSize)
//! Source: http://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/
inline double fastPow(double a, double b)
{
union
{
double d;
std::int32_t x[2];
} u = { a };
u.x[1] = static_cast<std::int32_t>(b * (u.x[1] - 1072632447) + 1072632447);
u.x[0] = 0;
return u.d;
double d;
std::int32_t x[2];

std::memcpy(x, &a, sizeof(x));
x[1] = static_cast<std::int32_t>(b * (x[1] - 1072632447) + 1072632447);
x[0] = 0;

std::memcpy(&d, x, sizeof(d));
return d;
}


Expand Down

0 comments on commit a61a6ff

Please sign in to comment.