ICU-1271 Add copyright header
X-SVN-Rev: 6186
This commit is contained in:
parent
a0d55f3957
commit
c542f7ece6
@ -1,3 +1,18 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2001, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: llong.cpp
|
||||
* encoding: US-ASCII
|
||||
* tab size: 8 (not used)
|
||||
* indentation:4
|
||||
*
|
||||
* Modification history
|
||||
* Date Name Comments
|
||||
* 10/11/2001 Doug Ported from ICU4J (thanks to Mike Cowlishaw)
|
||||
*/
|
||||
|
||||
#include "llong.h"
|
||||
|
||||
#if 0
|
||||
@ -42,260 +57,268 @@ const double llong::kDMin = -kDMax;
|
||||
|
||||
llong& llong::operator*=(const llong& rhs)
|
||||
{
|
||||
// optimize small positive multiplications
|
||||
if (hi == 0 && rhs.hi == 0 && lo < SQRT231 && rhs.lo < SQRT231) {
|
||||
lo *= rhs.lo;
|
||||
} else {
|
||||
int retry = 0;
|
||||
// optimize small positive multiplications
|
||||
if (hi == 0 && rhs.hi == 0 && lo < SQRT231 && rhs.lo < SQRT231) {
|
||||
lo *= rhs.lo;
|
||||
} else {
|
||||
int retry = 0;
|
||||
|
||||
llong a(*this);
|
||||
if (a.isNegative()) {
|
||||
retry = 1;
|
||||
a.negate();
|
||||
}
|
||||
llong a(*this);
|
||||
if (a.isNegative()) {
|
||||
retry = 1;
|
||||
a.negate();
|
||||
}
|
||||
|
||||
llong b(rhs);
|
||||
if (b.isNegative()) {
|
||||
retry = 1;
|
||||
b.negate();
|
||||
}
|
||||
llong b(rhs);
|
||||
if (b.isNegative()) {
|
||||
retry = 1;
|
||||
b.negate();
|
||||
}
|
||||
|
||||
llong r;
|
||||
// optimize small negative multiplications
|
||||
if (retry && a.hi == 0 && b.hi == 0 && a.lo < SQRT231 && b.lo < SQRT231) {
|
||||
r.lo = a.lo * b.lo;
|
||||
} else {
|
||||
if (a < b) {
|
||||
llong t = a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
while (b.notZero()) {
|
||||
if (b.lo & 0x1) {
|
||||
r += a;
|
||||
}
|
||||
b >>= 1;
|
||||
a <<= 1;
|
||||
}
|
||||
}
|
||||
if (isNegative() != rhs.isNegative()) {
|
||||
r.negate();
|
||||
}
|
||||
*this = r;
|
||||
}
|
||||
return *this;
|
||||
llong r;
|
||||
// optimize small negative multiplications
|
||||
if (retry && a.hi == 0 && b.hi == 0 && a.lo < SQRT231 && b.lo < SQRT231) {
|
||||
r.lo = a.lo * b.lo;
|
||||
} else {
|
||||
if (a < b) {
|
||||
llong t = a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
while (b.notZero()) {
|
||||
if (b.lo & 0x1) {
|
||||
r += a;
|
||||
}
|
||||
b >>= 1;
|
||||
a <<= 1;
|
||||
}
|
||||
}
|
||||
if (isNegative() != rhs.isNegative()) {
|
||||
r.negate();
|
||||
}
|
||||
*this = r;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
llong& llong::operator/=(const llong& rhs)
|
||||
{
|
||||
if (isZero()) {
|
||||
return *this;
|
||||
}
|
||||
int32_t sign = 1;
|
||||
llong a(*this);
|
||||
if (a.isNegative()) {
|
||||
sign = -1;
|
||||
a.negate();
|
||||
}
|
||||
llong b(rhs);
|
||||
if (b.isNegative()) {
|
||||
sign = -sign;
|
||||
b.negate();
|
||||
}
|
||||
if (isZero()) {
|
||||
return *this;
|
||||
}
|
||||
int32_t sign = 1;
|
||||
llong a(*this);
|
||||
if (a.isNegative()) {
|
||||
sign = -1;
|
||||
a.negate();
|
||||
}
|
||||
llong b(rhs);
|
||||
if (b.isNegative()) {
|
||||
sign = -sign;
|
||||
b.negate();
|
||||
}
|
||||
|
||||
if (b.isZero()) { // should throw div by zero error
|
||||
*this = sign < 0 ? kMinValue : kMaxValue;
|
||||
} else if (a.hi == 0 && b.hi == 0) {
|
||||
*this = (int32_t)(sign * (a.lo / b.lo));
|
||||
} else if (b > a) {
|
||||
*this = kZero;
|
||||
} else if (b == a) {
|
||||
*this = sign;
|
||||
} else {
|
||||
llong r;
|
||||
llong m((int32_t)1);
|
||||
if (b.isZero()) { // should throw div by zero error
|
||||
*this = sign < 0 ? kMinValue : kMaxValue;
|
||||
} else if (a.hi == 0 && b.hi == 0) {
|
||||
*this = (int32_t)(sign * (a.lo / b.lo));
|
||||
} else if (b > a) {
|
||||
*this = kZero;
|
||||
} else if (b == a) {
|
||||
*this = sign;
|
||||
} else {
|
||||
llong r;
|
||||
llong m((int32_t)1);
|
||||
|
||||
while (ule(b, a)) { // a positive so topmost bit is 0, this will always terminate
|
||||
m <<= 1;
|
||||
b <<= 1;
|
||||
}
|
||||
while (ule(b, a)) { // a positive so topmost bit is 0, this will always terminate
|
||||
m <<= 1;
|
||||
b <<= 1;
|
||||
}
|
||||
|
||||
do {
|
||||
m.ushr(1); // don't sign-extend!
|
||||
if (m.isZero()) break;
|
||||
do {
|
||||
m.ushr(1); // don't sign-extend!
|
||||
if (m.isZero()) break;
|
||||
|
||||
b.ushr(1);
|
||||
if (b <= a) {
|
||||
r |= m;
|
||||
a -= b;
|
||||
}
|
||||
} while (a >= rhs);
|
||||
b.ushr(1);
|
||||
if (b <= a) {
|
||||
r |= m;
|
||||
a -= b;
|
||||
}
|
||||
} while (a >= rhs);
|
||||
|
||||
if (sign < 0) {
|
||||
r.negate();
|
||||
}
|
||||
*this = r;
|
||||
}
|
||||
return *this;
|
||||
if (sign < 0) {
|
||||
r.negate();
|
||||
}
|
||||
*this = r;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
static uint8_t asciiDigits[] = {
|
||||
(char)0x30, (char)0x31, (char)0x32, (char)0x33, (char)0x34, (char)0x35, (char)0x36, (char)0x37,
|
||||
(char)0x38, (char)0x39, (char)0x61, (char)0x62, (char)0x63, (char)0x64, (char)0x65, (char)0x66,
|
||||
(char)0x67, (char)0x68, (char)0x69, (char)0x6a, (char)0x6b, (char)0x6c, (char)0x6d, (char)0x6e,
|
||||
(char)0x6f, (char)0x70, (char)0x71, (char)0x72, (char)0x73, (char)0x74, (char)0x75, (char)0x76,
|
||||
(char)0x77, (char)0x78, (char)0x79, (char)0x7a,
|
||||
static const uint8_t asciiDigits[] = {
|
||||
0x30u, 0x31u, 0x32u, 0x33u, 0x34u, 0x35u, 0x36u, 0x37u,
|
||||
0x38u, 0x39u, 0x61u, 0x62u, 0x63u, 0x64u, 0x65u, 0x66u,
|
||||
0x67u, 0x68u, 0x69u, 0x6au, 0x6bu, 0x6cu, 0x6du, 0x6eu,
|
||||
0x6fu, 0x70u, 0x71u, 0x72u, 0x73u, 0x74u, 0x75u, 0x76u,
|
||||
0x77u, 0x78u, 0x79u, 0x7au,
|
||||
};
|
||||
|
||||
static UChar kUMinus = (UChar)0x002d;
|
||||
static char kMinus = (char)0x2d;
|
||||
static const UChar kUMinus = (UChar)0x002d;
|
||||
static const char kMinus = 0x2d;
|
||||
|
||||
static uint8_t digitInfo[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0, 0, 0, 0, 0, 0,
|
||||
0, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
|
||||
0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0, 0, 0, 0, 0,
|
||||
0, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
|
||||
0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0, 0, 0, 0, 0,
|
||||
static const uint8_t digitInfo[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0x80u, 0x81u, 0x82u, 0x83u, 0x84u, 0x85u, 0x86u, 0x87u,
|
||||
0x88u, 0x89u, 0, 0, 0, 0, 0, 0,
|
||||
0, 0x8au, 0x8bu, 0x8cu, 0x8du, 0x8eu, 0x8fu, 0x90u,
|
||||
0x91u, 0x92u, 0x93u, 0x94u, 0x95u, 0x96u, 0x97u, 0x98u,
|
||||
0x99u, 0x9au, 0x9bu, 0x9cu, 0x9du, 0x9eu, 0x9fu, 0xa0u,
|
||||
0xa1u, 0xa2u, 0xa3u, 0, 0, 0, 0, 0,
|
||||
0, 0x8au, 0x8bu, 0x8cu, 0x8du, 0x8eu, 0x8fu, 0x90u,
|
||||
0x91u, 0x92u, 0x93u, 0x94u, 0x95u, 0x96u, 0x97u, 0x98u,
|
||||
0x99u, 0x9au, 0x9bu, 0x9cu, 0x9du, 0x9eu, 0x9fu, 0xa0u,
|
||||
0xa1u, 0xa2u, 0xa3u, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
llong atoll(const char* str, uint32_t radix)
|
||||
{
|
||||
if (radix > 36) {
|
||||
radix = 36;
|
||||
} else if (radix < 2) {
|
||||
radix = 2;
|
||||
}
|
||||
llong lradix(radix);
|
||||
if (radix > 36) {
|
||||
radix = 36;
|
||||
} else if (radix < 2) {
|
||||
radix = 2;
|
||||
}
|
||||
llong lradix(radix);
|
||||
|
||||
int neg = 0;
|
||||
if (*str == kMinus) {
|
||||
++str;
|
||||
neg = 1;
|
||||
}
|
||||
llong result;
|
||||
uint8_t b;
|
||||
while ((b = digitInfo[*str++]) && ((b &= 0x7f) < radix)) {
|
||||
result *= lradix;
|
||||
result += (int32_t)b;
|
||||
}
|
||||
if (neg) {
|
||||
result.negate();
|
||||
}
|
||||
return result;
|
||||
int neg = 0;
|
||||
if (*str == kMinus) {
|
||||
++str;
|
||||
neg = 1;
|
||||
}
|
||||
llong result;
|
||||
uint8_t b;
|
||||
while ((b = digitInfo[*str++]) && ((b &= 0x7f) < radix)) {
|
||||
result *= lradix;
|
||||
result += (int32_t)b;
|
||||
}
|
||||
if (neg) {
|
||||
result.negate();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
llong u_atoll(const UChar* str, uint32_t radix)
|
||||
{
|
||||
if (radix > 36) {
|
||||
radix = 36;
|
||||
} else if (radix < 2) {
|
||||
radix = 2;
|
||||
}
|
||||
llong lradix(radix);
|
||||
if (radix > 36) {
|
||||
radix = 36;
|
||||
} else if (radix < 2) {
|
||||
radix = 2;
|
||||
}
|
||||
llong lradix(radix);
|
||||
|
||||
int neg = 0;
|
||||
if (*str == kUMinus) {
|
||||
++str;
|
||||
neg = 1;
|
||||
}
|
||||
llong result;
|
||||
UChar c;
|
||||
uint8_t b;
|
||||
while (((c = *str++) < 0x0080) && (b = digitInfo[c]) && ((b &= 0x7f) < radix)) {
|
||||
result *= lradix;
|
||||
result += (int32_t)b;
|
||||
}
|
||||
if (neg) {
|
||||
result.negate();
|
||||
}
|
||||
return result;
|
||||
int neg = 0;
|
||||
if (*str == kUMinus) {
|
||||
++str;
|
||||
neg = 1;
|
||||
}
|
||||
llong result;
|
||||
UChar c;
|
||||
uint8_t b;
|
||||
while (((c = *str++) < 0x0080) && (b = digitInfo[c]) && ((b &= 0x7f) < radix)) {
|
||||
result *= lradix;
|
||||
result += (int32_t)b;
|
||||
}
|
||||
if (neg) {
|
||||
result.negate();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t lltoa(const llong& val, char* buf, uint32_t len, uint32_t radix, UBool raw)
|
||||
{
|
||||
if (radix > 36) {
|
||||
radix = 36;
|
||||
} else if (radix < 2) {
|
||||
radix = 2;
|
||||
}
|
||||
llong base(radix);
|
||||
{
|
||||
if (radix > 36) {
|
||||
radix = 36;
|
||||
} else if (radix < 2) {
|
||||
radix = 2;
|
||||
}
|
||||
llong base(radix);
|
||||
|
||||
char* p = buf;
|
||||
llong w(val);
|
||||
if (len && w.isNegative()) {
|
||||
w.negate();
|
||||
*p++ = kMinus;
|
||||
--len;
|
||||
}
|
||||
char* p = buf;
|
||||
llong w(val);
|
||||
if (len && w.isNegative()) {
|
||||
w.negate();
|
||||
*p++ = kMinus;
|
||||
--len;
|
||||
}
|
||||
|
||||
while (len && w.notZero()) {
|
||||
llong n = w / base;
|
||||
llong m = n * base;
|
||||
int32_t d = llong_asInt(w-m);
|
||||
*p++ = raw ? (char)d : asciiDigits[d];
|
||||
w = n;
|
||||
--len;
|
||||
}
|
||||
if (len) {
|
||||
*p = 0; // null terminate if room for caller convenience
|
||||
}
|
||||
while (len && w.notZero()) {
|
||||
llong n = w / base;
|
||||
llong m = n * base;
|
||||
int32_t d = llong_asInt(w-m);
|
||||
*p++ = raw ? (char)d : asciiDigits[d];
|
||||
w = n;
|
||||
--len;
|
||||
}
|
||||
if (len) {
|
||||
*p = 0; // null terminate if room for caller convenience
|
||||
}
|
||||
|
||||
len = p - buf;
|
||||
if (*buf == kMinus) {
|
||||
++buf;
|
||||
}
|
||||
while (--p > buf) {
|
||||
char c = *p;
|
||||
*p = *buf;
|
||||
*buf = c;
|
||||
++buf;
|
||||
}
|
||||
len = p - buf;
|
||||
if (*buf == kMinus) {
|
||||
++buf;
|
||||
}
|
||||
while (--p > buf) {
|
||||
char c = *p;
|
||||
*p = *buf;
|
||||
*buf = c;
|
||||
++buf;
|
||||
}
|
||||
|
||||
return len;
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32_t u_lltoa(const llong& val, UChar* buf, uint32_t len, uint32_t radix, UBool raw)
|
||||
{
|
||||
if (radix > 36) {
|
||||
radix = 36;
|
||||
} else if (radix < 2) {
|
||||
radix = 2;
|
||||
}
|
||||
llong base(radix);
|
||||
{
|
||||
if (radix > 36) {
|
||||
radix = 36;
|
||||
} else if (radix < 2) {
|
||||
radix = 2;
|
||||
}
|
||||
llong base(radix);
|
||||
|
||||
UChar* p = buf;
|
||||
llong w(val);
|
||||
if (len && w.isNegative()) {
|
||||
w.negate();
|
||||
*p++ = kUMinus;
|
||||
--len;
|
||||
}
|
||||
UChar* p = buf;
|
||||
llong w(val);
|
||||
if (len && w.isNegative()) {
|
||||
w.negate();
|
||||
*p++ = kUMinus;
|
||||
--len;
|
||||
}
|
||||
|
||||
while (len && w.notZero()) {
|
||||
llong n = w / base;
|
||||
llong m = n * base;
|
||||
int32_t d = llong_asInt(w-m);
|
||||
*p++ = (UChar)(raw ? d : asciiDigits[d]);
|
||||
w = n;
|
||||
--len;
|
||||
}
|
||||
if (len) {
|
||||
*p = 0; // null terminate if room for caller convenience
|
||||
}
|
||||
while (len && w.notZero()) {
|
||||
llong n = w / base;
|
||||
llong m = n * base;
|
||||
int32_t d = llong_asInt(w-m);
|
||||
*p++ = (UChar)(raw ? d : asciiDigits[d]);
|
||||
w = n;
|
||||
--len;
|
||||
}
|
||||
if (len) {
|
||||
*p = 0; // null terminate if room for caller convenience
|
||||
}
|
||||
|
||||
len = p - buf;
|
||||
if (*buf == kUMinus) {
|
||||
++buf;
|
||||
}
|
||||
while (--p > buf) {
|
||||
UChar c = *p;
|
||||
*p = *buf;
|
||||
*buf = c;
|
||||
++buf;
|
||||
}
|
||||
len = p - buf;
|
||||
if (*buf == kUMinus) {
|
||||
++buf;
|
||||
}
|
||||
while (--p > buf) {
|
||||
UChar c = *p;
|
||||
*p = *buf;
|
||||
*buf = c;
|
||||
++buf;
|
||||
}
|
||||
|
||||
return len;
|
||||
return len;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user