1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "stdafx.h"
18 
19 #include <cerrno>
20 #include <cstdlib>
21 
22 #include "util/cxx_util.h"
23 #include "util/string_util.h"
24 
25 #include "integer.h"
26 #include "decimal.h"
27 #include "floatimpl.h"
28 #include "numconversions.h"
29 
30 #ifdef ZORBA_WITH_BIG_INTEGER
31 # define TEMPLATE_DECL(T) /* nothing */
32 # define INTEGER_IMPL(T)  IntegerImpl
33 #else
34 # define TEMPLATE_DECL(T) template<typename T> /* spacer */
35 # define INTEGER_IMPL(T)  IntegerImpl<T> /* spacer */
36 #endif /* ZORBA_WITH_BIG_INTEGER */
37 #define INTEGER_IMPL_LL  INTEGER_IMPL(long long)
38 #define INTEGER_IMPL_ULL INTEGER_IMPL(unsigned long long)
39 
40 using namespace std;
41 
42 #ifndef ZORBA_WITH_BIG_INTEGER
43 unsigned long long MaxUIntegerValue = ~0ull >> 1;
44 
is_too_big(long long)45 inline bool is_too_big( long long ) {
46   return false;
47 }
48 
is_too_big(unsigned long long n)49 inline bool is_too_big( unsigned long long n ) {
50   return n > MaxUIntegerValue;
51 }
52 #endif /* ZORBA_WITH_BIG_INTEGER */
53 
54 namespace zorba {
55 
56 ///////////////////////////////////////////////////////////////////////////////
57 
TEMPLATE_DECL(I)58 TEMPLATE_DECL(I)
59 void INTEGER_IMPL(I)::parse( char const *s ) {
60 #ifdef ZORBA_WITH_BIG_INTEGER
61   Decimal::parse( s, &value_, Decimal::parse_integer );
62 #else
63   value_type const temp( ztd::aton<value_type>( s ) );
64   if ( is_too_big( temp ) )
65     throw std::invalid_argument(
66       BUILD_STRING( '"', temp, "\": unsigned integer too big" )
67     );
68   value_ = temp;
69 #endif /* ZORBA_WITH_BIG_INTEGER */
70 }
71 
72 ////////// constructors ///////////////////////////////////////////////////////
73 
74 #ifdef ZORBA_WITH_BIG_INTEGER
IntegerImpl(long long n)75 IntegerImpl::IntegerImpl( long long n ) {
76   ztd::itoa_buf_type buf;
77   value_ = ztd::itoa( n, buf );
78 }
79 
IntegerImpl(unsigned long n)80 IntegerImpl::IntegerImpl( unsigned long n ) {
81   ztd::itoa_buf_type buf;
82   value_ = ztd::itoa( n, buf );
83 }
84 
IntegerImpl(unsigned long long n)85 IntegerImpl::IntegerImpl( unsigned long long n ) {
86   ztd::itoa_buf_type buf;
87   value_ = ztd::itoa( n, buf );
88 }
89 #endif /* ZORBA_WITH_BIG_INTEGER */
90 
91 TEMPLATE_DECL(T)
INTEGER_IMPL(T)92 INTEGER_IMPL(T)::IntegerImpl( Decimal const &d ) {
93   value_ = ftoi( d.value_ );
94 }
95 
96 TEMPLATE_DECL(T)
INTEGER_IMPL(T)97 INTEGER_IMPL(T)::IntegerImpl( Double const &d ) {
98   if ( !d.isFinite() )
99     throw std::invalid_argument( "not finite" );
100   value_ = ftoi( d.getNumber() );
101 }
102 
103 TEMPLATE_DECL(T)
INTEGER_IMPL(T)104 INTEGER_IMPL(T)::IntegerImpl( Float const &f ) {
105   if ( !f.isFinite() )
106     throw std::invalid_argument( "not finite" );
107   value_ = ftoi( f.getNumber() );
108 }
109 
110 ////////// assignment operators ///////////////////////////////////////////////
111 
112 #ifdef ZORBA_WITH_BIG_INTEGER
operator =(long long n)113 IntegerImpl& IntegerImpl::operator=( long long n ) {
114   ztd::itoa_buf_type buf;
115   value_ = ztd::itoa( n, buf );
116   return *this;
117 }
118 
operator =(unsigned long n)119 IntegerImpl& IntegerImpl::operator=( unsigned long n ) {
120   ztd::itoa_buf_type buf;
121   value_ = ztd::itoa( n, buf );
122   return *this;
123 }
124 
operator =(unsigned long long n)125 IntegerImpl& IntegerImpl::operator=( unsigned long long n ) {
126   ztd::itoa_buf_type buf;
127   value_ = ztd::itoa( n, buf );
128   return *this;
129 }
130 #endif /* ZORBA_WITH_BIG_INTEGER */
131 
132 TEMPLATE_DECL(T)
INTEGER_IMPL(T)133 INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( Decimal const &d ) {
134   value_ = ftoi( d.value_ );
135   return *this;
136 }
137 
138 TEMPLATE_DECL(T)
INTEGER_IMPL(T)139 INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( Double const &d ) {
140   if ( !d.isFinite() )
141     throw std::invalid_argument( "not finite" );
142   value_ = ftoi( d.getNumber() );
143   return *this;
144 }
145 
146 TEMPLATE_DECL(T)
INTEGER_IMPL(T)147 INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( Float const &f ) {
148   if ( !f.isFinite() )
149     throw std::invalid_argument( "not finite" );
150   value_ = ftoi( f.getNumber() );
151   return *this;
152 }
153 
154 ////////// arithmetic operators ///////////////////////////////////////////////
155 
156 #ifdef ZORBA_WITH_BIG_INTEGER
157 # define ZORBA_INSTANTIATE(OP) /* nothing */
158 #else
159 # define ZORBA_INSTANTIATE(OP)                                            \
160   template Decimal operator OP( INTEGER_IMPL_LL const&, Decimal const& ); \
161   template Decimal operator OP( INTEGER_IMPL_ULL const&, Decimal const& );
162 #endif /* ZORBA_WITH_BIG_INTEGER */
163 
164 #define ZORBA_INTEGER_OP(OP)                                          \
165   TEMPLATE_DECL(T)                                                    \
166   Decimal operator OP( INTEGER_IMPL(T) const &i, Decimal const &d ) { \
167     return i.itod() OP d.value_;                                      \
168   }                                                                   \
169   ZORBA_INSTANTIATE(OP)
170 
171 ZORBA_INTEGER_OP(+)
172 ZORBA_INTEGER_OP(-)
173 ZORBA_INTEGER_OP(*)
174 ZORBA_INTEGER_OP(/)
175 ZORBA_INTEGER_OP(%)
176 #undef ZORBA_INTEGER_OP
177 #undef ZORBA_INSTANTIATE
178 
179 #ifdef ZORBA_WITH_BIG_INTEGER
180 
181 #define ZORBA_INTEGER_OP(OP,T)                                          \
182   IntegerImpl operator OP( IntegerImpl const &i, T n ) {                \
183     ztd::itoa_buf_type buf;                                             \
184     return i.value_ OP IntegerImpl::value_type( ztd::itoa( n, buf ) );  \
185   }                                                                     \
186   IntegerImpl operator OP( T n, IntegerImpl const &i ) {                \
187     ztd::itoa_buf_type buf;                                             \
188     return IntegerImpl::value_type( ztd::itoa( n, buf ) ) OP i.value_;  \
189   }
190 
191 ZORBA_INTEGER_OP(+,long long)
192 ZORBA_INTEGER_OP(-,long long)
193 ZORBA_INTEGER_OP(*,long long)
194 ZORBA_INTEGER_OP(%,long long)
195 ZORBA_INTEGER_OP(+,unsigned long)
196 ZORBA_INTEGER_OP(-,unsigned long)
197 ZORBA_INTEGER_OP(*,unsigned long)
198 ZORBA_INTEGER_OP(%,unsigned long)
199 ZORBA_INTEGER_OP(+,unsigned long long)
200 ZORBA_INTEGER_OP(-,unsigned long long)
201 ZORBA_INTEGER_OP(*,unsigned long long)
202 ZORBA_INTEGER_OP(%,unsigned long long)
203 #undef ZORBA_INTEGER_OP
204 
205 #define ZORBA_INTEGER_OP(T)                                     \
206   IntegerImpl operator/( IntegerImpl const &i, T n ) {          \
207     ztd::itoa_buf_type buf;                                     \
208     IntegerImpl::value_type const temp( ztd::itoa( n, buf ) );  \
209     return IntegerImpl::ftoi( i.value_ / temp );                \
210   }                                                             \
211   IntegerImpl operator/( T n, IntegerImpl const &i ) {          \
212     ztd::itoa_buf_type buf;                                     \
213     IntegerImpl::value_type const temp( ztd::itoa( n, buf ) );  \
214     return IntegerImpl::ftoi( temp / i.value_ );                \
215   }
216 
217 ZORBA_INTEGER_OP(long long)
218 ZORBA_INTEGER_OP(unsigned long)
219 ZORBA_INTEGER_OP(unsigned long long)
220 #undef ZORBA_INTEGER_OP
221 
222 #define ZORBA_INTEGER_OP(OP,T)                    \
223   IntegerImpl& IntegerImpl::operator OP( T n ) {  \
224     ztd::itoa_buf_type buf;                       \
225     value_type const temp( ztd::itoa( n, buf ) ); \
226     value_ OP temp;                               \
227     return *this;                                 \
228   }
229 
230 ZORBA_INTEGER_OP(+=,long long)
231 ZORBA_INTEGER_OP(-=,long long)
232 ZORBA_INTEGER_OP(*=,long long)
233 ZORBA_INTEGER_OP(%=,long long)
234 ZORBA_INTEGER_OP(+=,unsigned long)
235 ZORBA_INTEGER_OP(-=,unsigned long)
236 ZORBA_INTEGER_OP(*=,unsigned long)
237 ZORBA_INTEGER_OP(%=,unsigned long)
238 ZORBA_INTEGER_OP(+=,unsigned long long)
239 ZORBA_INTEGER_OP(-=,unsigned long long)
240 ZORBA_INTEGER_OP(*=,unsigned long long)
241 ZORBA_INTEGER_OP(%=,unsigned long long)
242 #undef ZORBA_INTEGER_OP
243 
244 #define ZORBA_INTEGER_OP(T) \
245   IntegerImpl& IntegerImpl::operator/=( T n ) {   \
246     ztd::itoa_buf_type buf;                       \
247     value_type const temp( ztd::itoa( n, buf ) ); \
248     value_ = ftoi( value_ / temp );               \
249     return *this;                                 \
250   }
251 
252 ZORBA_INTEGER_OP(long long)
253 ZORBA_INTEGER_OP(unsigned long)
254 ZORBA_INTEGER_OP(unsigned long long)
255 #undef ZORBA_INTEGER_OP
256 #endif /* ZORBA_WITH_BIG_INTEGER */
257 
258 ////////// relational operators ///////////////////////////////////////////////
259 
260 TEMPLATE_DECL(T)
261 bool operator==( INTEGER_IMPL(T) const &i, Decimal const &d ) {
262   return d.is_xs_integer() && i.itod() == d.value_;
263 }
264 
265 #define ZORBA_INTEGER_OP(OP)                                        \
266   TEMPLATE_DECL(T)                                                  \
267   bool operator OP( INTEGER_IMPL(T) const &i, Decimal const &d ) {  \
268     return i.itod() OP d.value_;                                    \
269   }
270 
271 ZORBA_INTEGER_OP(!=)
272 ZORBA_INTEGER_OP(< )
273 ZORBA_INTEGER_OP(<=)
274 ZORBA_INTEGER_OP(> )
275 ZORBA_INTEGER_OP(>=)
276 #undef ZORBA_INTEGER_OP
277 
278 #ifdef ZORBA_WITH_BIG_INTEGER
279 
280 #define ZORBA_INTEGER_OP(OP,T) \
281   bool operator OP( IntegerImpl const &i, T n ) {                       \
282     ztd::itoa_buf_type buf;                                             \
283     return i.value_ OP IntegerImpl::value_type( ztd::itoa( n, buf ) );  \
284   }                                                                     \
285                                                                         \
286   bool operator OP( T n, IntegerImpl const &i ) {                       \
287     ztd::itoa_buf_type buf;                                             \
288     return IntegerImpl::value_type( ztd::itoa( n, buf ) ) OP i.value_;  \
289   }
290 
291 ZORBA_INTEGER_OP(==,long long)
292 ZORBA_INTEGER_OP(!=,long long)
293 ZORBA_INTEGER_OP(< ,long long)
294 ZORBA_INTEGER_OP(<=,long long)
295 ZORBA_INTEGER_OP(> ,long long)
296 ZORBA_INTEGER_OP(>=,long long)
297 ZORBA_INTEGER_OP(==,unsigned long)
298 ZORBA_INTEGER_OP(!=,unsigned long)
299 ZORBA_INTEGER_OP(< ,unsigned long)
300 ZORBA_INTEGER_OP(<=,unsigned long)
301 ZORBA_INTEGER_OP(> ,unsigned long)
302 ZORBA_INTEGER_OP(>=,unsigned long)
303 ZORBA_INTEGER_OP(==,unsigned long long)
304 ZORBA_INTEGER_OP(!=,unsigned long long)
305 ZORBA_INTEGER_OP(< ,unsigned long long)
306 ZORBA_INTEGER_OP(<=,unsigned long long)
307 ZORBA_INTEGER_OP(> ,unsigned long long)
308 ZORBA_INTEGER_OP(>=,unsigned long long)
309 
310 #else /* ZORBA_WITH_BIG_INTEGER */
311 
312 #define ZORBA_INSTANTIATE(OP)                                           \
313   template bool operator OP( INTEGER_IMPL_LL const&, Decimal const& );  \
314   template bool operator OP( INTEGER_IMPL_ULL const&, Decimal const& )
315 
316 ZORBA_INSTANTIATE(==);
317 ZORBA_INSTANTIATE(!=);
318 ZORBA_INSTANTIATE(< );
319 ZORBA_INSTANTIATE(<=);
320 ZORBA_INSTANTIATE(> );
321 ZORBA_INSTANTIATE(>=);
322 #undef ZORBA_INSTANTIATE
323 
324 #endif /* ZORBA_WITH_BIG_INTEGER */
325 
326 ////////// math functions /////////////////////////////////////////////////////
327 
TEMPLATE_DECL(T)328 TEMPLATE_DECL(T)
329 Double INTEGER_IMPL(T)::pow( INTEGER_IMPL(T) const &power ) const {
330 #ifdef ZORBA_WITH_BIG_INTEGER
331   value_type const result( value_.pow( power.value_, 15 ) );
332   char buf[300];
333   result.toFixPtString( buf, 15 );
334   return Double( buf );
335 #else
336   return Double(
337     // The casts are needed for disambiguation with MSVC++.
338     ::pow( static_cast<double>( value_ ), static_cast<double>( power.value_ ) )
339   );
340 #endif /* ZORBA_WITH_BIG_INTEGER */
341 }
342 
343 TEMPLATE_DECL(T)
INTEGER_IMPL(T)344 INTEGER_IMPL(T) INTEGER_IMPL(T)::round( IntegerImpl const &precision ) const {
345   return IntegerImpl( Decimal::round2( itod(), precision.itod() ) );
346 }
347 
348 TEMPLATE_DECL(T)
INTEGER_IMPL(T)349 INTEGER_IMPL(T)
350 INTEGER_IMPL(T)::roundHalfToEven( IntegerImpl const &precision ) const {
351   return IntegerImpl( Decimal::roundHalfToEven2( itod(), precision.itod() ) );
352 }
353 
354 ////////// miscellaneous //////////////////////////////////////////////////////
355 
356 #ifndef ZORBA_WITH_BIG_INTEGER
TEMPLATE_DECL(T)357 TEMPLATE_DECL(T)
358 typename INTEGER_IMPL(T)::value_type INTEGER_IMPL(T)::ftoi( MAPM const &d ) {
359   MAPM const temp( d.sign() >= 0 ? d.floor() : d.ceil() );
360   char *const buf = new char[ temp.exponent() + 3 ];
361   temp.toIntegerString( buf );
362   value_type const result( ztd::aton<value_type>( buf ) );
363   delete[] buf;
364   return result;
365 }
366 
TEMPLATE_DECL(T)367 TEMPLATE_DECL(T)
368 MAPM INTEGER_IMPL(T)::itod() const {
369   if ( is_cxx_long() )
370     return static_cast<long>( value_ );
371   ztd::itoa_buf_type buf;
372   return ztd::itoa( value_, buf );
373 }
374 #endif /* ZORBA_WITH_BIG_INTEGER */
375 
376 #ifdef ZORBA_WITH_BIG_INTEGER
hash() const377 uint32_t IntegerImpl::hash() const {
378   return Decimal::hash( value_ );
379 }
380 
is_xs_byte() const381 bool IntegerImpl::is_xs_byte() const {
382   static MAPM xs_byte_min( "-128" );
383   static MAPM xs_byte_max( "127" );
384   return value_ >= xs_byte_min && value_ <= xs_byte_max;
385 }
386 
is_xs_short() const387 bool IntegerImpl::is_xs_short() const {
388   static MAPM xs_short_min( "-32768" );
389   static MAPM xs_short_max( "32767" );
390   return value_ >= xs_short_min && value_ <= xs_short_max;
391 }
392 
is_xs_unsignedByte() const393 bool IntegerImpl::is_xs_unsignedByte() const {
394   static MAPM xs_unsignedByte_max( "256" );
395   return value_.sign() >= 0 && value_ <= xs_unsignedByte_max;
396 }
397 
is_xs_unsignedInt() const398 bool IntegerImpl::is_xs_unsignedInt() const {
399   static MAPM xs_unsignedInt_max( "4294967295" );
400   return value_.sign() >= 0 && value_ <= xs_unsignedInt_max;
401 }
402 
is_xs_unsignedLong() const403 bool IntegerImpl::is_xs_unsignedLong() const {
404   static MAPM xs_unsignedLong_max( "18446744073709551615" );
405   return value_.sign() >= 0 && value_ <= xs_unsignedLong_max;
406 }
407 
is_xs_unsignedShort() const408 bool IntegerImpl::is_xs_unsignedShort() const {
409   static MAPM xs_unsignedShort_max( "65536" );
410   return value_.sign() >= 0 && value_ <= xs_unsignedShort_max;
411 }
412 #endif /* ZORBA_WITH_BIG_INTEGER */
413 
414 TEMPLATE_DECL(T)
INTEGER_IMPL(T) const415 INTEGER_IMPL(T) const& INTEGER_IMPL(T)::one() {
416   static INTEGER_IMPL(T) const i(1);
417   return i;
418 }
419 
TEMPLATE_DECL(T)420 TEMPLATE_DECL(T)
421 zstring INTEGER_IMPL(T)::toString() const {
422 #ifdef ZORBA_WITH_BIG_INTEGER
423   char *const buf = new char[ value_.exponent() + 3 ];
424   value_.toIntegerString( buf );
425   zstring const result( buf );
426   delete[] buf;
427   return result;
428 #else
429   ztd::itoa_buf_type buf;
430   return ztd::itoa( value_, buf );
431 #endif /* ZORBA_WITH_BIG_INTEGER */
432 }
433 
434 TEMPLATE_DECL(T)
INTEGER_IMPL(T) const435 INTEGER_IMPL(T) const& INTEGER_IMPL(T)::zero() {
436   static INTEGER_IMPL(T) const i(0);
437   return i;
438 }
439 
440 ///////////////////////////////////////////////////////////////////////////////
441 
442 #ifndef ZORBA_WITH_BIG_INTEGER
443 template class IntegerImpl<long long>;
444 template class IntegerImpl<unsigned long long>;
445 #endif /* ZORBA_WITH_BIG_INTEGER */
446 
447 } // namespace zorba
448 /* vim:set et sw=2 ts=2: */
449