⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 int96.cpp

📁 96位大数运算实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
Module : INT96.CPP
Purpose: Implementation for an 96 bit integer class
Created: PJN / 26-04-1999
History: PJN / 17-10-1999 1. Fix for the function FormatAsDecimal which was
                          failing when the number starts with a "10".
         PJN / 26-10-1999 1. Fixed bug in operator!=
                          2. Fixed bug in operator^
                          3. Fixed bug in operator| 
                          4. Fixed bug in operator&
                          5. All relational and equality operators now return
                          "int" instead of BOOL
                          6. Provision of operators which convert back to
                          basic C types.
                          7. Improved the performance of operator*
                          8. Fixed problem with 0/0 which was returning 0 
                          instead of the correct value undefined i.e. divide 
                          by 0 exception
         PJN / 28-10-1999 1. Fixed another bug in operator!=
                          2. removed the use of MAXDWORD and replaced with 0xFFFFFFFF
         PJN / 14-11-1999 1. Fixed a bug in operator*
         

Copyright (c) 1999 by PJ Naughter.  
All rights reserved.

*/

///////////////////////////////// Includes //////////////////////////////////
#include "stdafx.h"
#include "int96.h"


///////////////////////////////// Defines ///////////////////////////////////

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


//////////////////////////////// implementation /////////////////////////////

CInt96::CInt96()
{
  m_MSB = 0;
  m_CSB = 0;
  m_LSB = 0;
}

CInt96::CInt96(unsigned short value)
{
  m_MSB = 0;
  m_CSB = 0;
  m_LSB = value;
}

CInt96::CInt96(unsigned int value)
{
  m_MSB = 0;
  m_CSB = 0;
  m_LSB = value;
}

CInt96::CInt96(unsigned long value)
{
  m_MSB = 0;
  m_CSB = 0;
  m_LSB = value;
}

CInt96::CInt96(const unsigned __int64& value)
{
  m_MSB = 0;
  m_CSB = (DWORD) ((value >> 32) & 0xFFFFFFFF);
  m_LSB = (DWORD) (value & 0xFFFFFFFF);
}

CInt96::CInt96(short value)
{
  if (value < 0)
  {
    *this = CInt96((unsigned short)-value);
    TwosComplement();
  }
  else
  {
    m_MSB = 0;
    m_CSB = 0;
    m_LSB = value;
  }
}

CInt96::CInt96(int value)
{
  if (value < 0)
  {
    *this = CInt96((unsigned int)-value);
    TwosComplement();
  }
  else
  {
    m_MSB = 0;
    m_CSB = 0;
    m_LSB = value;
  }
}

CInt96::CInt96(long value)
{
  if (value < 0)
  {
    *this = CInt96((unsigned long)-value);
    TwosComplement();
  }
  else
  {
    m_MSB = 0;
    m_CSB = 0;
    m_LSB = value;
  }
}

CInt96::CInt96(const __int64& value)
{
  if (value < 0)
  {
    *this = CInt96((unsigned __int64)-value);
    TwosComplement();
  }
  else
  {
    m_MSB = 0;
    m_CSB = (DWORD) ((value >> 32) & 0xFFFFFFFF);
    m_LSB = (DWORD) (value & 0xFFFFFFFF);
  }
}

CInt96::CInt96(const CInt96& value)
{
  *this = value;
}

CInt96& CInt96::operator=(const CInt96& value)
{
  m_MSB = value.m_MSB;
  m_CSB = value.m_CSB;
  m_LSB = value.m_LSB;
  
  return *this;
}

CInt96 CInt96::operator+(const CInt96& value)
{
  CInt96 rVal;

  unsigned __int64 t = ((unsigned __int64)m_LSB) + ((unsigned __int64)value.m_LSB);
  int nCarry = (t > 0xFFFFFFFF);
  rVal.m_LSB = (DWORD) (t);

  t = ((unsigned __int64)m_CSB) + ((unsigned __int64)value.m_CSB) + nCarry;
  nCarry = (t > 0xFFFFFFFF);
  rVal.m_CSB = (DWORD) (t);

  t = ((unsigned __int64)m_MSB) + ((unsigned __int64)value.m_MSB) + nCarry;
  rVal.m_MSB = (DWORD) (t);

  return rVal;
}

CInt96 CInt96::operator-(const CInt96& value)
{
  CInt96 rVal;

  unsigned __int64 t = ((unsigned __int64)m_LSB) - ((unsigned __int64)value.m_LSB);
  int nCarry = (t > 0xFFFFFFFF);
  rVal.m_LSB = (DWORD) (t);

  t = ((unsigned __int64)m_CSB) - ((unsigned __int64)value.m_CSB) - nCarry;
  nCarry = (t > 0xFFFFFFFF);
  rVal.m_CSB = (DWORD) (t);

  t = ((unsigned __int64)m_MSB) - ((unsigned __int64)value.m_MSB) - nCarry;
  rVal.m_MSB = (DWORD) (t);

  return rVal;
}

CInt96 operator-(const CInt96& value)
{
  CInt96 rVal(value);
  rVal.operator~();

  return rVal;
}

CInt96& CInt96::operator++()
{
  *this = *this + CInt96(1);
  return *this;
}

CInt96& CInt96::operator--()
{
  *this = *this - CInt96(1);
  return *this;
}

CInt96& CInt96::operator*=(const CInt96& value)
{
  *this = *this * value;
  return *this;
}

CInt96& CInt96::operator/=(const CInt96& value)
{
  *this = *this / value;
  return *this;
}

CInt96& CInt96::operator+=(const CInt96& value)
{
  *this = *this + value;
  return *this;
}

CInt96& CInt96::operator-=(const CInt96& value)
{
  *this = *this - value;
  return *this;
}

CInt96 CInt96::operator~() const
{
  CInt96 rVal;

  rVal.m_MSB = ~m_MSB;
  rVal.m_CSB = ~m_CSB;
  rVal.m_LSB = ~m_LSB;

  return rVal;
}

void CInt96::Negate()
{
  if (IsPositive())
    TwosComplement();
  else
    InverseTwosComplement();
}

int CInt96::operator==(const CInt96& value) const
{
  return (m_MSB == value.m_MSB) && (m_CSB == value.m_CSB) && (m_LSB == value.m_LSB);
}

int CInt96::operator!=(const CInt96& value) const
{
  return (m_MSB != value.m_MSB) || (m_CSB != value.m_CSB) || (m_LSB != value.m_LSB);
}

int CInt96::operator>(const CInt96& value) const
{
  if (m_MSB > value.m_MSB)
    return TRUE;
  else if (m_MSB == value.m_MSB)
  {
    if (m_CSB > value.m_CSB)
      return TRUE;
    else if (m_CSB == value.m_CSB)
      return (m_LSB > value.m_LSB);
    else
      return FALSE;
  }
  else 
    return FALSE;
}

int CInt96::operator>=(const CInt96& value) const
{
  return operator>(value) || operator==(value);
}

int CInt96::operator<(const CInt96& value) const
{
  if (m_MSB < value.m_MSB)
    return TRUE;
  else if (m_MSB == value.m_MSB)
  {
    if (m_CSB < value.m_CSB)
      return TRUE;
    else if (m_CSB == value.m_CSB)
      return (m_LSB < value.m_LSB);
    else
      return FALSE;
  }
  else 
    return FALSE;
}

int CInt96::operator<=(const CInt96& value) const
{
  return operator<(value) || operator==(value);
}

BOOL CInt96::IsZero() const
{
  return (m_MSB == 0) && (m_CSB == 0) && (m_LSB == 0);
}

void CInt96::Zero()
{
  m_MSB = 0;
  m_CSB = 0;
  m_LSB = 0;
}

BOOL CInt96::IsNegative() const
{
  return ((m_MSB & 0x80000000) != 0);
}

BOOL CInt96::IsPositive() const
{
  return ((m_MSB & 0x80000000) == 0);
}

void CInt96::Serialize(CArchive& ar)
{
  if (ar.IsLoading())
  {
    WORD wVersion;
    ar >> wVersion;

    ar >> m_MSB;
    ar >> m_CSB;
    ar >> m_LSB;
  }
  else
  {
    WORD wVersion = 0x100; //Version 1.
    ar << wVersion;

    ar << m_MSB;
    ar << m_CSB;
    ar << m_LSB;
  }
}

void CInt96::TwosComplement()
{
  m_MSB = ~m_MSB;
  m_CSB = ~m_CSB;
  m_LSB = ~m_LSB;
  operator++();
}

void CInt96::InverseTwosComplement()
{
  operator--();
  m_MSB = ~m_MSB;
  m_CSB = ~m_CSB;
  m_LSB = ~m_LSB;
}

CInt96 CInt96::operator>>(int nShift) const
{
  CInt96 rVal;

  if (nShift >= 0)
  {
    if (nShift == 32)
    {
      rVal.m_LSB = m_CSB;
      rVal.m_CSB = m_MSB;
      rVal.m_MSB = 0;
    }
    else if (nShift == 0)
    {
      rVal.m_LSB = m_LSB;
      rVal.m_CSB = m_CSB;
      rVal.m_MSB = m_MSB;
    }
    else if (nShift == 64)
    {
      rVal.m_LSB = m_MSB;
      rVal.m_CSB = 0;
      rVal.m_MSB = 0;
    }
    else if (nShift < 32)
    {
      rVal.m_MSB = (m_MSB >> nShift);
      rVal.m_CSB = (m_CSB >> nShift) | (m_MSB << (32 - nShift));
      rVal.m_LSB = (m_LSB >> nShift) | (m_CSB << (32 - nShift));
    }
    else if (nShift < 64)
    {
      rVal.m_MSB = 0;
      rVal.m_CSB = m_MSB >> (nShift-32);
      rVal.m_LSB = (m_CSB >> (nShift-32)) | (m_MSB << (64 - nShift));
    }
    else if (nShift < 96)
    {
      rVal.m_MSB = 0;
      rVal.m_CSB = 0;
      rVal.m_LSB = m_MSB >> (nShift-64);
    }
    else
    {
      rVal.m_LSB = 0;
      rVal.m_CSB = 0;
      rVal.m_MSB = 0;
    }
  }
  else if (nShift < 0)
    rVal.operator<<(-nShift);

  return rVal;
}

CInt96 CInt96::operator<<(int nShift) const
{
  CInt96 rVal;

  if (nShift >= 0)
  {
    if (nShift == 32)
    {
      rVal.m_LSB = 0;
      rVal.m_CSB = m_LSB;
      rVal.m_MSB = m_CSB;
    }
    else if (nShift == 0)
    {
      rVal.m_LSB = m_LSB;
      rVal.m_CSB = m_CSB;
      rVal.m_MSB = m_MSB;
    }
    else if (nShift == 64)
    {
      rVal.m_LSB = 0;
      rVal.m_CSB = 0;
      rVal.m_MSB = m_LSB;
    }
    else if (nShift < 32)
    {
      rVal.m_LSB = m_LSB << nShift;
      rVal.m_CSB = (m_CSB << nShift) | (m_LSB >> (32 - nShift));
      rVal.m_MSB = (m_MSB << nShift) | (m_CSB >> (32 - nShift));
    }
    else if (nShift < 64)
    {
      rVal.m_LSB = 0;
      rVal.m_CSB = m_LSB << (nShift-32);
      rVal.m_MSB = (m_CSB << (nShift-32)) | (m_LSB >> (64 - nShift));
    }
    else if (nShift < 96)
    {
      rVal.m_LSB = 0;
      rVal.m_CSB = 0;
      rVal.m_MSB = m_LSB << (nShift-64);
    }
    else
    {
      rVal.m_MSB = 0;
      rVal.m_CSB = 0;
      rVal.m_LSB = 0;
    }
  }
  else if (nShift < 0)
    rVal.operator>>(-nShift);

  return rVal;
}

CInt96& CInt96::operator>>=(int nShift)
{
  *this = (*this >> nShift);
  return *this;
}

CInt96& CInt96::operator<<=(int nShift)
{
  *this = (*this << nShift);
  return *this;
}

CInt96 CInt96::operator*(const CInt96& value) const
{
  CInt96 A(*this);
  CInt96 B(value);

  // Correctly handle negative values
  BOOL bANegative = FALSE;
  BOOL bBNegative = FALSE;
  if (A.IsNegative())
  {
    bANegative = TRUE;
    A.Negate();

⌨️ 快捷键说明

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