?? int96.cpp
字號:
/*
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 + -