DGtal  1.4.beta
IntegerConverter.h
1 
17 #pragma once
18 
31 #if defined(IntegerConverter_RECURSES)
32 #error Recursive header files inclusion detected in IntegerConverter.h
33 #else // defined(IntegerConverter_RECURSES)
35 #define IntegerConverter_RECURSES
36 
37 #if !defined IntegerConverter_h
39 #define IntegerConverter_h
40 
42 // Inclusions
43 #include <iostream>
44 #include <string>
45 #include <vector>
46 #include <array>
47 #include "DGtal/base/Common.h"
48 #include "DGtal/kernel/CInteger.h"
49 #include "DGtal/kernel/NumberTraits.h"
50 #include "DGtal/kernel/PointVector.h"
51 
52 namespace DGtal
53 {
54 #ifdef WITH_BIGINTEGER
55  namespace detail {
57 
60  static inline void mpz_set_sll(mpz_t n, long long sll)
61  {
62  mpz_set_si(n, (int)(sll >> 32)); /* n = (int)sll >> 32 */
63  mpz_mul_2exp(n, n, 32 ); /* n <<= 32 */
64  mpz_add_ui(n, n, (unsigned int)sll); /* n += (unsigned int)sll */
65  }
66 
69  static inline void mpz_set_ull(mpz_t n, unsigned long long ull)
70  {
71  mpz_set_ui(n, (unsigned int)(ull >> 32)); /* n = (unsigned int)(ull >> 32) */
72  mpz_mul_2exp(n, n, 32); /* n <<= 32 */
73  mpz_add_ui(n, n, (unsigned int)ull); /* n += (unsigned int)ull */
74  }
75 
79  static inline unsigned long long mpz_get_ull(mpz_t n)
80  {
81  mpz_t tmp;
82  mpz_init( tmp );
83  mpz_mod_2exp( tmp, n, 64 ); /* tmp = (lower 64 bits of n) */
84  auto lo = mpz_get_ui( tmp ); /* lo = tmp & 0xffffffff */
85  mpz_div_2exp( tmp, tmp, 32 ); /* tmp >>= 32 */
86  auto hi = mpz_get_ui( tmp ); /* hi = tmp & 0xffffffff */
87  mpz_clear( tmp );
88  return (((unsigned long long)hi) << 32) + lo;
89  }
90 
94  static inline long long mpz_get_sll(mpz_t n)
95  {
96  return (long long)mpz_get_ull(n); /* just use unsigned version */
97  }
98  }
99 #endif
100 
102 
114  template < DGtal::Dimension dim,
115  typename TInteger >
118  typedef TInteger Integer;
119 
122  static Integer cast( Integer i )
123  {
124  return i;
125  }
126 
131  static
134  {
135  return p;
136  }
137  };
138 
148  template < DGtal::Dimension dim >
151 
155  {
156  return i;
157  }
158 
163  static
166  {
167  return p;
168  }
169 
173  {
175  if ( DGtal::int64_t( r ) != i )
176  trace.warning() << "Bad integer conversion: " << i << " -> " << r
177  << std::endl;
178  return r;
179  }
180 
185  static
188  {
190  for ( DGtal::Dimension i = 0; i < dim; i++ )
191  q[ i ] = cast( p[ i ] );
192  return q;
193  }
194 
195 #ifdef WITH_BIGINTEGER
199  {
200  auto r = i.get_si();
201  if ( DGtal::BigInteger( r ) != i )
202  trace.warning() << "Bad integer conversion: " << i << " -> " << r
203  << std::endl;
204  return (DGtal::int32_t)r;
205  }
206 
211  static
214  {
216  for ( DGtal::Dimension i = 0; i < dim; i++ )
217  q[ i ] = cast( p[ i ] );
218  return q;
219  }
220 
221 #endif
222  };
223 
224 
234  template < DGtal::Dimension dim >
237 
241  {
242  return i;
243  }
244 
249  static
252  {
254  for ( DGtal::Dimension i = 0; i < dim; i++ )
255  q[ i ] = cast( p[ i ] );
256  return q;
257  }
258 
262  {
263  return i;
264  }
265 
270  static
273  {
274  return p;
275  }
276 
277 #ifdef WITH_BIGINTEGER
281  {
282  DGtal::int64_t r = detail::mpz_get_sll( i.get_mpz_t() );
283  DGtal::BigInteger tmp;
284  detail::mpz_set_sll( tmp.get_mpz_t(), r );
285  if ( tmp != i )
286  trace.warning() << "Bad integer conversion: " << i << " -> " << r
287  << std::endl;
288  return r;
289  }
290 
295  static
298  {
300  for ( DGtal::Dimension i = 0; i < dim; i++ )
301  q[ i ] = cast( p[ i ] );
302  return q;
303  }
304 
305 #endif
306  };
307 
308 
309 #ifdef WITH_BIGINTEGER
319  template < DGtal::Dimension dim >
322 
326  {
327  return DGtal::BigInteger( i );
328  }
329 
334  static
337  {
339  for ( DGtal::Dimension i = 0; i < dim; i++ )
340  q[ i ] = cast( p[ i ] );
341  return q;
342  }
343 
347  {
348  DGtal::BigInteger tmp;
349  detail::mpz_set_sll( tmp.get_mpz_t(), i );
350  return tmp;
351  }
352 
357  static
360  {
362  for ( DGtal::Dimension i = 0; i < dim; i++ )
363  q[ i ] = cast( p[ i ] );
364  return q;
365  }
366 
370  {
371  return i;
372  }
373 
378  static
381  {
382  return p;
383  }
384 
385  };
386 #endif
387 
388 
389 } // namespace DGtal {
390 
391 #endif // !defined IntegerConverter_h
392 
393 #undef IntegerConverter_RECURSES
394 #endif // else defined(IntegerConverter_RECURSES)
std::ostream & warning()
static void mpz_set_sll(mpz_t n, long long sll)
----------— GMP SPECIALIZED SERVICES -------------------------—
static long long mpz_get_sll(mpz_t n)
static unsigned long long mpz_get_ull(mpz_t n)
static void mpz_set_ull(mpz_t n, unsigned long long ull)
DGtal is the top-level namespace which contains all DGtal functions and types.
boost::int64_t int64_t
signed 94-bit integer.
Definition: BasicTypes.h:74
DGtal::uint32_t Dimension
Definition: Common.h:136
Trace trace
Definition: Common.h:153
boost::int32_t int32_t
signed 32-bit integer.
Definition: BasicTypes.h:72
mpz_class BigInteger
Multi-precision integer with GMP implementation.
Definition: BasicTypes.h:79
static PointVector< dim, DGtal::BigInteger > cast(PointVector< dim, DGtal::BigInteger > p)
static DGtal::BigInteger cast(DGtal::int32_t i)
static PointVector< dim, DGtal::BigInteger > cast(PointVector< dim, DGtal::int32_t > p)
static PointVector< dim, DGtal::BigInteger > cast(PointVector< dim, DGtal::int64_t > p)
static DGtal::BigInteger cast(DGtal::BigInteger i)
static DGtal::BigInteger cast(DGtal::int64_t i)
static DGtal::int32_t cast(DGtal::int32_t i)
static PointVector< dim, DGtal::int32_t > cast(PointVector< dim, DGtal::int64_t > p)
static PointVector< dim, DGtal::int32_t > cast(PointVector< dim, DGtal::BigInteger > p)
static DGtal::int32_t cast(DGtal::BigInteger i)
static PointVector< dim, DGtal::int32_t > cast(PointVector< dim, DGtal::int32_t > p)
static DGtal::int32_t cast(DGtal::int64_t i)
static DGtal::int64_t cast(DGtal::int32_t i)
static PointVector< dim, DGtal::int64_t > cast(PointVector< dim, DGtal::int64_t > p)
static DGtal::int64_t cast(DGtal::int64_t i)
static PointVector< dim, DGtal::int64_t > cast(PointVector< dim, DGtal::BigInteger > p)
static PointVector< dim, DGtal::int64_t > cast(PointVector< dim, DGtal::int32_t > p)
static DGtal::int64_t cast(DGtal::BigInteger i)
----------— INTEGER/POINT CONVERSION SERVICES -----------------—
BOOST_CONCEPT_ASSERT((concepts::CInteger< TInteger >))
static PointVector< dim, Integer > cast(PointVector< dim, Integer > p)
static Integer cast(Integer i)
Aim: Concept checking for Integer Numbers. More precisely, this concept is a refinement of both CEucl...
Definition: CInteger.h:88
unsigned int dim(const Vector &z)