16 : sign_(
'+'), data_(
""), exp_(0L)
19 char const* p = r.c_str();
20 while (*p ==
' ' || *p ==
'\t' || *p ==
'\n' || *p ==
'\r') ++p;
21 if (*p ==
'-')
sign_ =
'-', ++p;
22 else if (*p ==
'+') ++p;
23 if (*p ==
'I' && *++p ==
'n' && *++p ==
'f') {
data_ =
"Inf"; }
24 else if (*p ==
'N' && *++p ==
'a' && *++p ==
'N') {
data_ =
"NaN"; }
26 while (*p ==
'0') ++p;
27 while (*p >=
'0' && *p <=
'9')
data_.push_back(*p++);
30 while (*p >=
'0' && *p <=
'9') {
data_.push_back(*p++); --
exp; }
36 if (*p ==
'-')
sign =
'-', ++p;
37 else if (*p ==
'+') ++p;
38 while (*p ==
'0') ++p;
39 while (*p >=
'0' && *p <=
'9')
exp_ *= 10L,
exp_ += (*p-
'0'), ++p;
46 std::cerr <<
"Leaving vnl_decnum::vnl_decnum(\"" << r <<
"\") with " <<
sign_ <<
data_ <<
'e' <<
exp_ <<
'\n';
52 : sign_(
'+'), data_(
""), exp_(0L)
54 if (r == 0)
sign_ =
' ';
56 while (r) {
data_.insert(
data_.begin(),
'0'+(r%10)); r/=10; }
64 std::cerr <<
"vnl_decnum::vnl_decnum(double " << r <<
")\n";
66 std::ostringstream os; os << r;
72 vnl_decnum::operator std::string()
const 74 if (data_==
"NaN")
return "NaN";
75 if (sign_==
' ')
return "0";
76 std::string r=data_;
if (sign_==
'-') r.insert(r.begin(), sign_);
77 if (exp_ == 0)
return r;
80 long exp=exp_;
if (exp < 0) { exp = -exp; r.push_back(
'-'); }
82 while (exp) {e.insert(e.begin(),
'0'+(exp%10)); exp /=10; }
86 vnl_decnum::operator
unsigned long()
const 88 if (data_ ==
"NaN")
return 0L;
89 if (data_ ==
"Inf")
return 0xffffffffu;
91 for (
long i=0; i<long(data_.length())+exp_; ++i) { l *= 10;
if (i<
long(data_.length())) l += (data_.c_str()[i]-
'0'); }
95 vnl_decnum::operator long()
const 97 if (data_ ==
"NaN")
return 0L;
98 if (data_ ==
"Inf" && sign_ ==
'+')
return 0x7fffffff;
99 else if (data_ ==
"Inf")
return -0x7fffffff - 1;
101 for (
long i=0; i<long(data_.length())+exp_; ++i) { l *= 10;
if (i<
long(data_.length())) l += (data_.c_str()[i]-
'0'); }
102 return sign_==
'-' ? -l : l;
105 vnl_decnum::operator
unsigned int()
const 107 if (data_ ==
"NaN")
return 0L;
108 if (data_ ==
"Inf")
return 0xffffffffu;
110 for (
long i=0; i<long(data_.length())+exp_; ++i) { l *= 10;
if (i<
long(data_.length())) l += (data_.c_str()[i]-
'0'); }
114 vnl_decnum::operator int()
const 116 if (data_ ==
"NaN")
return 0L;
117 if (data_ ==
"Inf" && sign_ ==
'+')
return 0x7fffffff;
118 else if (data_ ==
"Inf")
return -0x7fffffff - 1;
120 for (
long i=0; i<long(data_.length())+exp_; ++i) { l *= 10;
if (i<
long(data_.length())) l += (data_.c_str()[i]-
'0'); }
121 return sign_==
'-' ? -l : l;
128 else if (
data_ ==
"NaN" || r.
data() ==
"NaN")
return false;
129 else if (
data_ ==
"Inf" && r.
data() ==
"Inf")
return true;
130 else if (
sign_ ==
' ')
return true;
149 std::cerr <<
"Entering vnl_decnum::comp with " << a <<
" and " << b <<
'\n';
151 int i, na = int(a.length()), nb =
int(b.length()), nc = na < nb ? na : nb;
152 for (i = 0; i < nc; ++i) {
153 if (a.c_str()[i] < b.c_str()[i])
return true;
154 else if (a.c_str()[i] > b.c_str()[i])
return false;
156 for (; i < nb; ++i) {
157 if (
'0' < b.c_str()[i])
return true;
165 std::cerr <<
"Entering vnl_decnum::operator< with " <<
data_ <<
" and " << r.
data() <<
'\n';
167 std::string rs = r.
data();
168 if (
data_ ==
"NaN" || rs ==
"NaN")
return false;
169 else if (
operator==(r))
return false;
171 else if (rs ==
"Inf")
return r.
sign() ==
'+';
173 if (
sign_==
'-' && r.
sign() ==
'-')
return -r <
operator-();
174 else if (
sign_==
'-')
return true;
175 else if (r.
sign() ==
'-')
return false;
176 else if (
sign_==
' ')
return true;
177 else if (r.
sign() ==
' ')
return false;
178 else if (
data_.length()+
exp_ < rs.length()+r.
exp())
return true;
179 else if (
data_.length()+
exp_ > rs.length()+r.
exp())
return false;
190 std::cerr <<
"Entering vnl_decnum::plus with " << a <<
" and " << b <<
'\n';
192 std::string result =
"";
193 int na=int(a.length()), nb=
int(b.length()), carry=0;
194 for (--na,--nb; na>=0&&nb>=0; --na,--nb) {
195 char c = a.c_str()[na] + (b.c_str()[nb] -
'0') + carry;
196 if (c >
'9') c-=10, carry=1;
else carry=0;
197 result.insert(result.begin(), c);
199 for (; na>=0&&nb<0; --na) {
200 char c = a.c_str()[na] + carry;
201 if (c >
'9') c-=10, carry=1;
else carry=0;
202 result.insert(result.begin(), c);
204 for (; nb>=0&&na<0; --nb) {
205 char c = b.c_str()[nb] + carry;
206 if (c >
'9') c-=10, carry=1;
else carry=0;
207 result.insert(result.begin(), c);
209 if (carry) result.insert(result.begin(),
'1');
220 std::cerr <<
"Entering vnl_decnum::minus with " << a <<
" and " << b <<
'\n';
222 std::string result =
"";
223 int na=int(a.length()), nb=
int(b.length()), carry=0;
225 for (--na,--nb; na>=0&&nb>=0; --na,--nb) {
226 char c = a.c_str()[na] - (b.c_str()[nb] -
'0') - carry;
227 if (c <
'0') c+=10, carry=1;
else carry=0;
228 result.insert(result.begin(), c);
230 for (; na>=0&&nb<0; --na) {
231 char c = a.c_str()[na] - carry;
232 if (c <
'0') c+=10, carry=1;
else carry=0;
233 result.insert(result.begin(), c);
235 for (na=0; result.c_str()[na]==
'0'; ++na) ;
236 if (na) result.erase(0, na);
244 std::cerr <<
"Entering vnl_decnum::operator+ with " 248 if (
data_ ==
"NaN")
return *
this;
249 else if (r.
data() ==
"NaN")
return r;
251 else if (
data_ ==
"Inf")
return *
this;
252 else if (r.
data() ==
"Inf")
return r;
254 if (
sign_ ==
' ')
return r;
255 else if (r.
sign() ==
' ')
return *
this;
256 else if (
operator==(-r))
return vnl_decnum(0L);
259 else if (
exp_ > r.
exp()) {
return r.operator+(*this); }
274 std::cerr <<
"Entering vnl_decnum::mult with " << a <<
" and " << b <<
'\n';
276 std::string result =
"";
277 int na=int(a.length()), carry=0, bb = b-
'0';
278 assert(bb >= 0 && bb <= 9);
279 for (--na; na>=0; --na) {
280 int c = (a.c_str()[na]-
'0') * bb + carry;
281 assert(c >= 0 && c <= 99);
283 result.insert(result.begin(),
'0'+c);
285 if (carry) result.insert(result.begin(),
'0'+carry);
292 std::cerr <<
"Entering vnl_decnum::operator* with " 296 if (
data_ ==
"NaN")
return *
this;
297 else if (r.
data() ==
"NaN")
return r;
298 else if (
data_ ==
"Inf" || r.
data() ==
"Inf")
305 if (
sign == 0)
return result;
306 std::string zeros =
"";
307 int na=int(
data_.length());
308 for (--na; na>=0; --na) {
310 zeros.push_back(
'0');
313 return (
sign==-1) ? -result : result;
324 std::cerr <<
"Entering vnl_decnum::div with " << a <<
" and " << b <<
'\n';
326 int na=int(a.length()), nb=
int(b.length());
330 while (nb<na) { b.push_back(
'0'), u.push_back(
'0'); ++nb; }
332 for (; u[0]<
'9'; u[0]++) {
344 std::cerr <<
"Entering vnl_decnum::operator/ with " 348 if (
data_ ==
"NaN")
return *
this;
349 else if (r.
data() ==
"NaN")
return r;
352 else if (
data_ ==
"Inf")
360 if (r == 1L)
return *
this;
361 if (
operator==(r))
return vnl_decnum(
'+',
"1",0L);
363 int na=int(a.length()), nb=
int(b.length());
365 while (na > nb || (na == nb && !
comp(a,b))) {
367 std::string d =
div(a, c);
369 std::cerr <<
"vnl_decnum::div returns " << d <<
'\n';
373 a =
m.data(); na=a.length();
377 return sign==-1 ? -result : result;
383 std::cerr <<
"Entering vnl_decnum::operator% with " 387 if (r == 0L)
return *
this;
388 else if (
data_ ==
"NaN")
return *
this;
389 else if (r.
data() ==
"NaN")
return r;
391 else if (
data_ ==
"Inf")
return *
this;
396 int na=int(a.length()), nb=
int(b.length());
397 while (na > nb || (na == nb && !
comp(a,b))) {
399 std::string d =
div(a, c);
401 std::cerr <<
"vnl_decnum::div returns " << d <<
'\n';
404 a =
m.data(); na=a.length();
414 std::cerr <<
"Entering operator>>(istream,vnl_decnum) with " << r <<
'\n';
416 std::string data =
"";
418 while (c ==
' ' || c ==
'\t' || c ==
'\r') c=s.get();
419 if (c == -1 || c ==
'\n') { r =
vnl_decnum(0L);
return s; }
420 if (c ==
'-') { data =
"-"; c=s.get(); }
421 else if (c ==
'+') c=s.get();
422 if (c ==
'I' && s.get() ==
'n' && s.get() ==
'f') { data +=
"Inf"; }
423 else if (c ==
'N' && s.get() ==
'a' && s.get() ==
'N') { data =
"NaN"; }
425 while (c ==
'0') c=s.get();
426 while ((c >=
'0' && c <=
'9') || c ==
'.') { data.push_back(c); c=s.get(); }
428 data.push_back(c); c=s.get();
429 if (c ==
'-' || c ==
'+') { data.push_back(c); c=s.get(); }
430 while (c >=
'0' && c <=
'9') { data.push_back(c); c=s.get(); }
434 if (c > 0) s.putback(c);
444 unsigned long n =
data_.find_last_not_of(
'0') + 1;
445 unsigned long l =
data_.length();
vnl_decnum & compactify()
Remove all trailing zeros from the mantissa, and increase the exponent accordingly.
vnl_decnum operator+() const
Unary plus operator.
static std::string div(std::string const &, std::string &)
Returns the largest one-significant-digit divisor of the two arguments.
vnl_decnum operator *(vnl_decnum const &r) const
Product.
bool operator<(vnl_decnum const &) const
static std::string mult(std::string const &, char)
Returns the product of the two arguments.
vnl_decnum()
Default constructor - creates the number zero.
Infinite precision numbers with decimal arithmetic.
static vnl_decnum plus(std::string const &, std::string const &, long)
Returns the sum of the two first arguments (interpreted as mantissas with the same exponent).
bool operator==(vnl_decnum const &) const
static bool comp(std::string const &, std::string const &)
This is "operator<" for strings.
static vnl_decnum minus(std::string const &, std::string const &, long)
Returns the difference of the two first arguments (interpreted as mantissas with the same exponent).
vnl_decnum operator/(vnl_decnum const &r) const
division operator.
vnl_decnum operator%(vnl_decnum const &r) const
modulo operator.
static std::string add_zeros(std::string const &source, unsigned long n)
VNL_EXPORT std::istream & operator>>(std::istream &s, vnl_decnum &r)
decimal input.
bool operator>(vnl_decnum const &r) const