Browse Source

core: fix a few implicit 64-to-32-bit casts in the real methods.

legacy
Sam Hocevar gary 13 years ago
parent
commit
52e44ef8be
1 changed files with 26 additions and 15 deletions
  1. +26
    -15
      src/real.cpp

+ 26
- 15
src/real.cpp View File

@@ -1,7 +1,7 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
@@ -12,6 +12,14 @@
# include "config.h"
#endif

#if defined WIN32 && !defined _XBOX
# define _USE_MATH_DEFINES /* for M_PI */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# undef near /* Fuck Microsoft */
# undef far /* Fuck Microsoft again */
#endif

#include <new>
#include <cstring>
#include <cstdio>
@@ -80,8 +88,8 @@ real::real(double d)
break;
}

m_mantissa[0] = u.x >> 20;
m_mantissa[1] = u.x << 12;
m_mantissa[0] = (uint32_t)(u.x >> 20);
m_mantissa[1] = (uint32_t)(u.x << 12);
memset(m_mantissa + 2, 0, (BIGITS - 2) * sizeof(m_mantissa[0]));
}

@@ -239,7 +247,7 @@ real real::operator +(real const &x) const
else if (i - bigoff == 0)
carry += (uint64_t)1 << (BIGIT_BITS - off);

ret.m_mantissa[i] = carry;
ret.m_mantissa[i] = (uint32_t)carry;
carry >>= BIGIT_BITS;
}

@@ -250,7 +258,8 @@ real real::operator +(real const &x) const
for (int i = 0; i < BIGITS; i++)
{
uint32_t tmp = ret.m_mantissa[i];
ret.m_mantissa[i] = (carry << (BIGIT_BITS - 1)) | (tmp >> 1);
ret.m_mantissa[i] = ((uint32_t)carry << (BIGIT_BITS - 1))
| (tmp >> 1);
carry = tmp & 1u;
}
ret.m_signexp++;
@@ -289,6 +298,7 @@ real real::operator -(real const &x) const

ret.m_signexp = m_signexp;

/* int64_t instead of uint64_t to preserve sign through shifts */
int64_t carry = 0;
for (int i = 0; i < bigoff; i++)
{
@@ -312,7 +322,7 @@ real real::operator -(real const &x) const
else if (i - bigoff == 0)
carry -= (uint64_t)1 << (BIGIT_BITS - off);

ret.m_mantissa[i] = carry;
ret.m_mantissa[i] = (uint32_t)carry;
carry >>= BIGIT_BITS;
carry |= carry << BIGIT_BITS;
}
@@ -422,8 +432,9 @@ real real::operator *(real const &x) const
carry--;
for (int i = 0; i < BIGITS; i++)
{
uint32_t tmp = ret.m_mantissa[i];
ret.m_mantissa[i] = (carry << (BIGIT_BITS - 1)) | (tmp >> 1);
uint32_t tmp = (uint32_t)ret.m_mantissa[i];
ret.m_mantissa[i] = ((uint32_t)carry << (BIGIT_BITS - 1))
| (tmp >> 1);
carry = tmp & 1u;
}
e++;
@@ -555,7 +566,7 @@ real re(real const &x)
/* Use the system's float inversion to approximate 1/x */
union { float f; uint32_t x; } u = { 1.0f }, v = { 1.0f };
v.x |= x.m_mantissa[0] >> 9;
v.f = 1.0 / v.f;
v.f = 1.0f / v.f;

real ret;
ret.m_mantissa[0] = v.x << 9;
@@ -598,7 +609,7 @@ real sqrt(real const &x)
union { float f; uint32_t x; } u = { 1.0f }, v = { 2.0f };
v.x -= ((x.m_signexp & 1) << 23);
v.x |= x.m_mantissa[0] >> 9;
v.f = 1.0 / sqrtf(v.f);
v.f = 1.0f / sqrtf(v.f);

real ret;
ret.m_mantissa[0] = v.x << 9;
@@ -980,7 +991,7 @@ real fmod(real const &x, real const &y)

real sin(real const &x)
{
bool switch_sign = x.m_signexp & 0x80000000u;
int switch_sign = x.m_signexp & 0x80000000u;

real absx = fmod(fabs(x), real::R_PI * 2);
if (absx > real::R_PI)
@@ -1041,7 +1052,7 @@ real tan(real const &x)
return cos(y) / sin(y);
}

static real asinacos(real const &x, bool is_asin, bool is_negative)
static inline real asinacos(real const &x, int is_asin, int is_negative)
{
/* Strategy for asin(): in [-0.5..0.5], use a Taylor series around
* zero. In [0.5..1], use asin(x) = π/2 - 2*asin(sqrt((1-x)/2)), and
@@ -1049,7 +1060,7 @@ static real asinacos(real const &x, bool is_asin, bool is_negative)
* Strategy for acos(): use acos(x) = π/2 - asin(x) and try not to
* lose the precision around x=1. */
real absx = fabs(x);
bool around_zero = (absx < (real::R_1 / 2));
int around_zero = (absx < (real::R_1 / 2));

if (!around_zero)
absx = sqrt((real::R_1 - absx) / 2);
@@ -1086,12 +1097,12 @@ static real asinacos(real const &x, bool is_asin, bool is_negative)

real asin(real const &x)
{
return asinacos(x, true, x.m_signexp >> 31);
return asinacos(x, 1, x.m_signexp >> 31);
}

real acos(real const &x)
{
return asinacos(x, false, x.m_signexp >> 31);
return asinacos(x, 0, x.m_signexp >> 31);
}

real atan(real const &x)


Loading…
Cancel
Save