longlong.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,199 行 · 第 1/2 页

CPP
1,199
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        wx/longlong.cpp
// Purpose:     implementation of wxLongLongNative
// Author:      Jeffrey C. Ollie <jeff@ollie.clive.ia.us>, Vadim Zeitlin
// Remarks:     this class is not public in wxWidgets 2.0! It is intentionally
//              not documented and is for private use only.
// Modified by:
// Created:     10.02.99
// RCS-ID:      $Id: longlong.cpp,v 1.41 2005/08/28 00:03:27 VZ Exp $
// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// ============================================================================
// headers
// ============================================================================

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
    #pragma implementation "longlong.h"
#endif

#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#if wxUSE_LONGLONG
#include "wx/longlong.h"
#include "wx/math.h"       // for fabs()

#if defined(__MWERKS__) && defined(__WXMSW__)
#include <string.h>     // for memset()
#else
#include <memory.h>     // for memset()
#endif

#include "wx/ioswrap.h"

// ============================================================================
// implementation
// ============================================================================

#if wxUSE_LONGLONG_NATIVE

// ----------------------------------------------------------------------------
// misc
// ----------------------------------------------------------------------------

void *wxLongLongNative::asArray() const
{
    static unsigned char temp[8];

    temp[0] = (unsigned char)((m_ll >> 56) & 0xFF);
    temp[1] = (unsigned char)((m_ll >> 48) & 0xFF);
    temp[2] = (unsigned char)((m_ll >> 40) & 0xFF);
    temp[3] = (unsigned char)((m_ll >> 32) & 0xFF);
    temp[4] = (unsigned char)((m_ll >> 24) & 0xFF);
    temp[5] = (unsigned char)((m_ll >> 16) & 0xFF);
    temp[6] = (unsigned char)((m_ll >> 8)  & 0xFF);
    temp[7] = (unsigned char)((m_ll >> 0)  & 0xFF);

    return temp;
}

void *wxULongLongNative::asArray() const
{
    static unsigned char temp[8];

    temp[0] = (unsigned char)((m_ll >> 56) & 0xFF);
    temp[1] = (unsigned char)((m_ll >> 48) & 0xFF);
    temp[2] = (unsigned char)((m_ll >> 40) & 0xFF);
    temp[3] = (unsigned char)((m_ll >> 32) & 0xFF);
    temp[4] = (unsigned char)((m_ll >> 24) & 0xFF);
    temp[5] = (unsigned char)((m_ll >> 16) & 0xFF);
    temp[6] = (unsigned char)((m_ll >> 8)  & 0xFF);
    temp[7] = (unsigned char)((m_ll >> 0)  & 0xFF);

    return temp;
}

#if wxUSE_LONGLONG_WX
wxLongLongNative::wxLongLongNative(wxLongLongWx ll)
{
    // assign first to avoid precision loss!
    m_ll = ll.GetHi();
    m_ll <<= 32;
    m_ll |= ll.GetLo();
}

wxLongLongNative& wxLongLongNative::operator=(wxLongLongWx ll)
{
    // assign first to avoid precision loss!
    m_ll = ll.GetHi();
    m_ll <<= 32;
    m_ll |= ll.GetLo();
    return *this;
}
#endif

#endif // wxUSE_LONGLONG_NATIVE

// ============================================================================
// wxLongLongWx: emulation of 'long long' using 2 longs
// ============================================================================

#if wxUSE_LONGLONG_WX

// assignment
wxLongLongWx& wxLongLongWx::Assign(double d)
{
    bool positive = d >= 0;
    d = fabs(d);
    if ( d <= ULONG_MAX )
    {
        m_hi = 0;
        m_lo = (long)d;
    }
    else
    {
        m_hi = (unsigned long)(d / (1.0 + (double)ULONG_MAX));
        m_lo = (unsigned long)(d - ((double)m_hi * (1.0 + (double)ULONG_MAX)));
    }

#ifdef wxLONGLONG_TEST_MODE
    m_ll = (wxLongLong_t)d;

    Check();
#endif // wxLONGLONG_TEST_MODE

    if ( !positive )
        Negate();

    return *this;
}

double wxLongLongWx::ToDouble() const
{
    double d = m_hi;
    d *= 1.0 + (double)ULONG_MAX;
    d += m_lo;

#ifdef wxLONGLONG_TEST_MODE
    wxASSERT( d == m_ll );
#endif // wxLONGLONG_TEST_MODE

    return d;
}

wxLongLongWx wxLongLongWx::operator<<(int shift) const
{
    wxLongLongWx ll(*this);
    ll <<= shift;

    return ll;
}

wxULongLongWx wxULongLongWx::operator<<(int shift) const
{
    wxULongLongWx ll(*this);
    ll <<= shift;

    return ll;
}

wxLongLongWx& wxLongLongWx::operator<<=(int shift)
{
    if (shift != 0)
    {
        if (shift < 32)
        {
            m_hi <<= shift;
            m_hi |= m_lo >> (32 - shift);
            m_lo <<= shift;
        }
        else
        {
            m_hi = m_lo << (shift - 32);
            m_lo = 0;
        }
    }

#ifdef wxLONGLONG_TEST_MODE
    m_ll <<= shift;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxULongLongWx& wxULongLongWx::operator<<=(int shift)
{
    if (shift != 0)
    {
        if (shift < 32)
        {
            m_hi <<= shift;
            m_hi |= m_lo >> (32 - shift);
            m_lo <<= shift;
        }
        else
        {
            m_hi = m_lo << (shift - 32);
            m_lo = 0;
        }
    }

#ifdef wxLONGLONG_TEST_MODE
    m_ll <<= shift;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxLongLongWx wxLongLongWx::operator>>(int shift) const
{
    wxLongLongWx ll(*this);
    ll >>= shift;

    return ll;
}

wxULongLongWx wxULongLongWx::operator>>(int shift) const
{
    wxULongLongWx ll(*this);
    ll >>= shift;

    return ll;
}

wxLongLongWx& wxLongLongWx::operator>>=(int shift)
{
    if (shift != 0)
    {
        if (shift < 32)
        {
            m_lo >>= shift;
            m_lo |= m_hi << (32 - shift);
            m_hi >>= shift;
        }
        else
        {
            m_lo = m_hi >> (shift - 32);
            m_hi = (m_hi < 0 ? -1L : 0);
        }
    }

#ifdef wxLONGLONG_TEST_MODE
    m_ll >>= shift;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxULongLongWx& wxULongLongWx::operator>>=(int shift)
{
    if (shift != 0)
    {
        if (shift < 32)
        {
            m_lo >>= shift;
            m_lo |= m_hi << (32 - shift);
            m_hi >>= shift;
        }
        else
        {
            m_lo = m_hi >> (shift - 32);
            m_hi = 0;
        }
    }

#ifdef wxLONGLONG_TEST_MODE
    m_ll >>= shift;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxLongLongWx wxLongLongWx::operator+(const wxLongLongWx& ll) const
{
    wxLongLongWx res(*this);
    res += ll;

    return res;
}

wxULongLongWx wxULongLongWx::operator+(const wxULongLongWx& ll) const
{
    wxULongLongWx res(*this);
    res += ll;

    return res;
}

wxLongLongWx wxLongLongWx::operator+(long l) const
{
    wxLongLongWx res(*this);
    res += l;

    return res;
}

wxULongLongWx wxULongLongWx::operator+(unsigned long l) const
{
    wxULongLongWx res(*this);
    res += l;

    return res;
}

wxLongLongWx& wxLongLongWx::operator+=(const wxLongLongWx& ll)
{
    unsigned long previous = m_lo;

    m_lo += ll.m_lo;
    m_hi += ll.m_hi;

    if ((m_lo < previous) || (m_lo < ll.m_lo))
        m_hi++;

#ifdef wxLONGLONG_TEST_MODE
    m_ll += ll.m_ll;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxULongLongWx& wxULongLongWx::operator+=(const wxULongLongWx& ll)
{
    unsigned long previous = m_lo;

    m_lo += ll.m_lo;
    m_hi += ll.m_hi;

    if ((m_lo < previous) || (m_lo < ll.m_lo))
        m_hi++;

#ifdef wxLONGLONG_TEST_MODE
    m_ll += ll.m_ll;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxLongLongWx& wxLongLongWx::operator+=(long l)
{
    unsigned long previous = m_lo;

    m_lo += l;
    if (l < 0)
        m_hi += -1l;

    if ((m_lo < previous) || (m_lo < (unsigned long)l))
        m_hi++;

#ifdef wxLONGLONG_TEST_MODE
    m_ll += l;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxULongLongWx& wxULongLongWx::operator+=(unsigned long l)
{
    unsigned long previous = m_lo;

    m_lo += l;

    if ((m_lo < previous) || (m_lo < l))
        m_hi++;

#ifdef wxLONGLONG_TEST_MODE
    m_ll += l;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

// pre increment
wxLongLongWx& wxLongLongWx::operator++()
{
    m_lo++;
    if (m_lo == 0)
        m_hi++;

#ifdef wxLONGLONG_TEST_MODE
    m_ll++;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxULongLongWx& wxULongLongWx::operator++()
{
    m_lo++;
    if (m_lo == 0)
        m_hi++;

#ifdef wxLONGLONG_TEST_MODE
    m_ll++;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

// negation
wxLongLongWx wxLongLongWx::operator-() const
{
    wxLongLongWx res(*this);
    res.Negate();

    return res;
}

wxLongLongWx& wxLongLongWx::Negate()
{
    m_hi = ~m_hi;
    m_lo = ~m_lo;

    m_lo++;
    if ( m_lo == 0 )
        m_hi++;

#ifdef wxLONGLONG_TEST_MODE
    m_ll = -m_ll;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

// subtraction

wxLongLongWx wxLongLongWx::operator-(const wxLongLongWx& ll) const
{
    wxLongLongWx res(*this);
    res -= ll;

    return res;
}

wxLongLongWx wxULongLongWx::operator-(const wxULongLongWx& ll) const
{
    wxASSERT(m_hi <= LONG_MAX );
    wxASSERT(ll.m_hi <= LONG_MAX );

    wxLongLongWx res( (long)m_hi , m_lo );
    wxLongLongWx op( (long)ll.m_hi , ll.m_lo );
    res -= op;

    return res;
}

wxLongLongWx& wxLongLongWx::operator-=(const wxLongLongWx& ll)
{
    unsigned long previous = m_lo;

    m_lo -= ll.m_lo;
    m_hi -= ll.m_hi;

    if (previous < ll.m_lo)
        m_hi--;

#ifdef wxLONGLONG_TEST_MODE
    m_ll -= ll.m_ll;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxULongLongWx& wxULongLongWx::operator-=(const wxULongLongWx& ll)
{
    unsigned long previous = m_lo;

    m_lo -= ll.m_lo;
    m_hi -= ll.m_hi;

    if (previous < ll.m_lo)
        m_hi--;

#ifdef wxLONGLONG_TEST_MODE
    m_ll -= ll.m_ll;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

// pre decrement
wxLongLongWx& wxLongLongWx::operator--()
{
    m_lo--;
    if (m_lo == 0xFFFFFFFF)
        m_hi--;

#ifdef wxLONGLONG_TEST_MODE
    m_ll--;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

wxULongLongWx& wxULongLongWx::operator--()
{
    m_lo--;
    if (m_lo == 0xFFFFFFFF)
        m_hi--;

#ifdef wxLONGLONG_TEST_MODE
    m_ll--;

    Check();
#endif // wxLONGLONG_TEST_MODE

    return *this;
}

// comparison operators

bool wxLongLongWx::operator<(const wxLongLongWx& ll) const
{
    if ( m_hi < ll.m_hi )
        return true;
    else if ( m_hi == ll.m_hi )
        return m_lo < ll.m_lo;
    else
        return false;
}

bool wxULongLongWx::operator<(const wxULongLongWx& ll) const
{
    if ( m_hi < ll.m_hi )
        return true;
    else if ( m_hi == ll.m_hi )
        return m_lo < ll.m_lo;
    else
        return false;
}

bool wxLongLongWx::operator>(const wxLongLongWx& ll) const
{
    if ( m_hi > ll.m_hi )
        return true;
    else if ( m_hi == ll.m_hi )
        return m_lo > ll.m_lo;
    else
        return false;
}

bool wxULongLongWx::operator>(const wxULongLongWx& ll) const
{
    if ( m_hi > ll.m_hi )
        return true;
    else if ( m_hi == ll.m_hi )
        return m_lo > ll.m_lo;
    else
        return false;
}

// bitwise operators

wxLongLongWx wxLongLongWx::operator&(const wxLongLongWx& ll) const
{
    return wxLongLongWx(m_hi & ll.m_hi, m_lo & ll.m_lo);
}

wxULongLongWx wxULongLongWx::operator&(const wxULongLongWx& ll) const
{
    return wxULongLongWx(m_hi & ll.m_hi, m_lo & ll.m_lo);
}

wxLongLongWx wxLongLongWx::operator|(const wxLongLongWx& ll) const
{
    return wxLongLongWx(m_hi | ll.m_hi, m_lo | ll.m_lo);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?