📄 vnl_bignum.cxx
字号:
// This is vxl/vnl/vnl_bignum.cxx
#include "vnl_bignum.h"
//:
// \file
#include <vcl_cctype.h> // Include character macros
#include <vcl_cstring.h> // for vcl_strlen
#include <vcl_cmath.h> // for vcl_fmod
#include <vcl_algorithm.h> // for vcl_copy
#include <vcl_vector.h>
#include <vcl_cassert.h>
#include <vcl_iostream.h>
#include <vnl/vnl_math.h> // for vnl_math_isfinite(double)
typedef unsigned short Counter;
typedef unsigned short Data;
// Used to create inf below. Can't
// use the constants directly because
// Visual Studio C++ will fail with a
// compiler error.
static long double zerold = 0.0L;
static double zerod = 0.0;
static float zerof = 0.0f;
//: Creates a zero vnl_bignum.
vnl_bignum::vnl_bignum ()
: count(0), sign(1), data(0)
{
}
//: Creates a vnl_bignum from a long integer.
vnl_bignum::vnl_bignum (long l)
: count(0), sign(1), data(0)
{
if (l < 0) { // Get correct sign
l = -l; // Get absolute value of l
this->sign = -1;
}
Data buf[sizeof(l)]; // Temp buffer to store l in
Counter i = 0; // buffer index
while (l) { // While more bits in l
assert(i < sizeof(l)); // no more buffer space
buf[i] = Data(l); // Peel off lower order bits
l >>= 16; // Shift next bits into place
++i;
}
if (i > 0)
this->data = new Data[this->count=i]; // Allocate permanent data
while (i--) // Save buffer into perm. data
this->data[i] = buf[i];
}
//: Creates a vnl_bignum from an integer.
vnl_bignum::vnl_bignum (int l)
: count(0), sign(1), data(0)
{
if (l < 0) { // Get correct sign
l = -l; // Get absolute value of l
this->sign = -1;
}
Data buf[sizeof(l)]; // Temp buffer to store l in
Counter i = 0; // buffer index
while (l) { // While more bits in l
assert(i < sizeof(l)); // no more buffer space
buf[i] = Data(l); // Peel off lower order bits
l >>= 16; // Shift next bits into place
i++;
}
if (i > 0)
this->data = new Data[this->count=i]; // Allocate permanent data
while (i--) // Save buffer into perm. data
this->data[i] = buf[i];
}
//: Creates a vnl_bignum from an unsigned long integer.
vnl_bignum::vnl_bignum (unsigned long l)
: count(0), sign(1), data(0)
{
Data buf[sizeof(l)]; // Temp buffer to store l in
Counter i = 0; // buffer index
while (l) { // While more bits in l
assert(i < sizeof(l)); // no more buffer space
buf[i] = Data(l); // Peel off lower order bits
l >>= 16; // Shift next bits into place
i++;
}
if (i > 0)
this->data = new Data[this->count=i]; // Allocate permanent data
while (i--) // Save buffer into perm. data
this->data[i] = buf[i];
}
//: Creates a vnl_bignum from an unsigned integer.
vnl_bignum::vnl_bignum (unsigned int l)
: count(0), sign(1), data(0)
{
Data buf[sizeof(l)]; // Temp buffer to store l in
Counter i = 0; // buffer index
while (l) { // While more bits in l
assert(i < sizeof(l)); // no more buffer space
buf[i] = Data(l); // Peel off lower order bits
l >>= 16; // Shift next bits into place
i++;
}
if (i > 0)
this->data = new Data[this->count=i]; // Allocate permanent data
while (i--) // Save buffer into perm. data
this->data[i] = buf[i];
}
//: Creates a vnl_bignum from a double floating point number.
vnl_bignum::vnl_bignum (double d)
: count(0), sign(1), data(0)
{
if (d < 0.0) { // Get sign of d
d = -d; // Get absolute value of d
this->sign = -1;
}
if (!vnl_math_isfinite(d)) {
// Infinity is represented as: count=1, data[0]=0.
// This is an otherwise unused representation, since 0 is represented as count=0.
this->count = 1;
this->data = new Data[1];
this->data[0] = 0;
} else if (d >= 1.0) {
// Note: 0x10000L == 1 >> 16: the (assumed) size of unsigned short is 16 bits.
vcl_vector<Data> buf;
while (d >= 1.0) {
buf.push_back( Data(vcl_fmod(d,0x10000L)) ); // Get next data "digit" from d
d /= 0x10000L; // Shift d right 1 data "digit"
}
// Allocate and copy into permanent buffer
this->data = buf.size()>0 ? new Data[buf.size()] : 0;
this->count = buf.size();
vcl_copy( buf.begin(), buf.end(), data );
}
}
vnl_bignum::vnl_bignum (float f)
: count(0), sign(1), data(0)
{
double d = f;
if (d < 0.0) { // Get sign of d
d = -d; // Get absolute value of d
this->sign = -1;
}
if (!vnl_math_isfinite(d)) {
// Infinity is represented as: count=1, data[0]=0.
// This is an otherwise unused representation, since 0 is represented as count=0.
this->count = 1;
this->data = new Data[1];
this->data[0] = 0;
} else if (d >= 1.0) {
// Note: 0x10000L == 1 >> 16: the (assumed) size of unsigned short is 16 bits.
vcl_vector<Data> buf;
while (d >= 1.0) {
buf.push_back( Data(vcl_fmod(d,0x10000L)) ); // Get next data "digit" from d
d /= 0x10000L; // Shift d right 1 data "digit"
}
// Allocate and copy into permanent buffer
this->data = buf.size()>0 ? new Data[buf.size()] : 0;
this->count = buf.size();
vcl_copy( buf.begin(), buf.end(), data );
}
}
//: Creates a vnl_bignum from a "long double" floating point number.
vnl_bignum::vnl_bignum (long double d)
: count(0), sign(1), data(0)
{
if (d < 0.0) { // Get sign of d
d = -d; // Get absolute value of d
this->sign = -1;
}
if (!vnl_math_isfinite(d)) {
// Infinity is represented as: count=1, data[0]=0.
// This is an otherwise unused representation, since 0 is represented as count=0.
this->count = 1;
this->data = new Data[1];
this->data[0] = 0;
} else if (d >= 1.0) {
// Note: 0x10000L == 1 >> 16: the (assumed) size of unsigned short is 16 bits.
vcl_vector<Data> buf;
while (d >= 1.0) {
buf.push_back( Data(vcl_fmod(d,0x10000L)) ); // Get next data "digit" from d
d /= 0x10000L; // Shift d right 1 data "digit"
}
// Allocate and copy into permanent buffer
this->data = (buf.size()>0 ? new Data[buf.size()] : 0);
this->count = buf.size();
vcl_copy( buf.begin(), buf.end(), data );
}
}
#if 0 // old, original Texas Instruments implementation - PVr
static bool is_decimal(const char *s)
{
if (*s == '+' || *s == '-') ++s;
if (*s < '1' || *s > '9') return false;
while (*s >= '0' && *s <= '9') ++s;
if (*s == 'l' || *s == 'L') ++s;
return *s == '\0';
}
static bool is_exponential(const char *s)
{
if (*s == '+' || *s == '-') ++s;
if (*s < '1' || *s > '9') return false;
while (*s >= '0' && *s <= '9') ++s;
if (*s != 'e' && *s != 'E') return false;
++s;
if (*s < '1' || *s > '9') return false;
while (*s >= '0' && *s <= '9') ++s;
return *s == '\0';
}
static bool is_hexadecimal(const char *s)
{
if (*s == '+' || *s == '-') ++s;
if (*s != '0') return false;
++s;
if (*s != 'x' && *s != 'X') return false;
++s;
if ((*s < '0' || *s > '9') &&
(*s < 'a' || *s > 'f') &&
(*s < 'A' || *s > 'F')) return false;
while ((*s >= '0' && *s <= '9') ||
(*s >= 'a' && *s <= 'f') ||
(*s >= 'A' && *s <= 'F')) ++s;
if (*s == 'l' || *s == 'L') ++s;
return *s == '\0';
}
static bool is_octal(const char *s)
{
if (*s == '+' || *s == '-') ++s;
if (*s != '0') return false;
while (*s >= '0' && *s <= '7') ++s;
if (*s == 'l' || *s == 'L') ++s;
return *s == '\0';
}
#else // new implementation, also to be used for operator>> - PVr
static char rt[4096];
static int rt_pos = 0;
static char next(const char*& s, vcl_istream** is)
{
if (!is || *s) { char c = *s; if (c) ++rt_pos, ++s; return c; }
if (rt_pos == 4096) return '\0';
(*is)->get(rt[rt_pos]); // read a single byte from istream
if (*s) ++s; // in case s == rt+rt_pos
rt[++rt_pos] = '\0'; return rt[rt_pos-1];
}
static bool is_decimal(const char* s, vcl_istream** is = 0)
{
rt_pos = 0;
char c = next(s,is);
while (c == ' ' || c == '\t' || c == '\n' || c == '\r') c = next(s,is);
if (c == '+' || c == '-') c = next(s,is);
if (c < '1' || c > '9') return false;
while (c >= '0' && c <= '9') c = next(s,is);
if (c == 'l' || c == 'L') c = next(s,is);
if (rt_pos > 0) rt[++rt_pos] = '\0';
return is ? true : c == '\0';
}
static bool is_exponential(const char* s, vcl_istream** is = 0)
{
rt_pos = 0;
char c = next(s,is);
while (c == ' ' || c == '\t' || c == '\n' || c == '\r') c = next(s,is);
if (c == '+' || c == '-') c = next(s,is);
if (c < '1' || c > '9') return false;
while (c >= '0' && c <= '9') c = next(s,is);
if (c != 'e' && c != 'E') return false;
c = next(s,is);
if (c == '+') c = next(s,is); // no negative exponent!
if (c < '0' || c > '9') return false;
while (c >= '0' && c <= '9') c = next(s,is);
if (rt_pos > 0) rt[++rt_pos] = '\0';
return is ? true : c == '\0';
}
static bool is_hexadecimal(const char* s, vcl_istream** is = 0)
{
rt_pos = 0;
char c = next(s,is);
while (c == ' ' || c == '\t' || c == '\n' || c == '\r') c = next(s,is);
if (c == '+' || c == '-') c = next(s,is);
if (c != '0') return false;
c = next(s,is);
if (c != 'x' && c != 'X') return false;
c = next(s,is);
if ((c < '0' || c > '9') &&
(c < 'a' || c > 'f') &&
(c < 'A' || c > 'F')) return false;
while ((c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F')) c = next(s,is);
if (c == 'l' || c == 'L') c = next(s,is);
if (rt_pos > 0) rt[++rt_pos] = '\0';
return is ? true : c == '\0';
}
static bool is_octal(const char* s, vcl_istream** is = 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -