~ubuntu-branches/ubuntu/oneiric/fparser/oneiric

« back to all changes in this revision

Viewing changes to mpfr/GmpInt.cc

  • Committer: Bazaar Package Importer
  • Author(s): Scott Howard
  • Date: 2011-04-07 21:19:16 UTC
  • Revision ID: james.westby@ubuntu.com-20110407211916-ejhqulkjialkv5fl
Tags: upstream-4.3
ImportĀ upstreamĀ versionĀ 4.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "GmpInt.hh"
 
2
#include <gmp.h>
 
3
#include <deque>
 
4
#include <vector>
 
5
#include <cstring>
 
6
#include <cctype>
 
7
 
 
8
//===========================================================================
 
9
// Shared data
 
10
//===========================================================================
 
11
namespace
 
12
{
 
13
    unsigned long gIntDefaultNumberOfBits = 256;
 
14
 
 
15
    std::vector<char>& intString()
 
16
    {
 
17
        static std::vector<char> str;
 
18
        return str;
 
19
    }
 
20
}
 
21
 
 
22
//===========================================================================
 
23
// Auxiliary structs
 
24
//===========================================================================
 
25
struct GmpInt::GmpIntData
 
26
{
 
27
    unsigned mRefCount;
 
28
    GmpIntData* nextFreeNode;
 
29
    mpz_t mInteger;
 
30
 
 
31
    GmpIntData(): mRefCount(1), nextFreeNode(0) {}
 
32
};
 
33
 
 
34
class GmpInt::GmpIntDataContainer
 
35
{
 
36
    std::deque<GmpInt::GmpIntData> mData;
 
37
    GmpInt::GmpIntData* mFirstFreeNode;
 
38
    GmpInt::GmpIntData* mConst_0;
 
39
 
 
40
 public:
 
41
    GmpIntDataContainer(): mFirstFreeNode(0), mConst_0(0) {}
 
42
 
 
43
    ~GmpIntDataContainer()
 
44
    {
 
45
        for(size_t i = 0; i < mData.size(); ++i)
 
46
            mpz_clear(mData[i].mInteger);
 
47
    }
 
48
 
 
49
    GmpInt::GmpIntData* allocateGmpIntData(unsigned long numberOfBits,
 
50
                                           bool initToZero)
 
51
    {
 
52
        if(mFirstFreeNode)
 
53
        {
 
54
            GmpInt::GmpIntData* node = mFirstFreeNode;
 
55
            mFirstFreeNode = node->nextFreeNode;
 
56
            if(initToZero) mpz_set_si(node->mInteger, 0);
 
57
            ++(node->mRefCount);
 
58
            return node;
 
59
        }
 
60
 
 
61
        mData.push_back(GmpInt::GmpIntData());
 
62
        if(numberOfBits > 0)
 
63
            mpz_init2(mData.back().mInteger, numberOfBits);
 
64
        else
 
65
            mpz_init(mData.back().mInteger);
 
66
        return &mData.back();
 
67
    }
 
68
 
 
69
    void releaseGmpIntData(GmpIntData* data)
 
70
    {
 
71
        if(--(data->mRefCount) == 0)
 
72
        {
 
73
            data->nextFreeNode = mFirstFreeNode;
 
74
            mFirstFreeNode = data;
 
75
        }
 
76
    }
 
77
 
 
78
    GmpInt::GmpIntData* const_0()
 
79
    {
 
80
        if(!mConst_0)
 
81
            mConst_0 = allocateGmpIntData(gIntDefaultNumberOfBits, true);
 
82
        return mConst_0;
 
83
    }
 
84
};
 
85
 
 
86
 
 
87
GmpInt::GmpIntDataContainer& GmpInt::gmpIntDataContainer()
 
88
{
 
89
    static GmpIntDataContainer container;
 
90
    return container;
 
91
}
 
92
 
 
93
//===========================================================================
 
94
// Auxiliary functions
 
95
//===========================================================================
 
96
void GmpInt::setDefaultNumberOfBits(unsigned long value)
 
97
{
 
98
    gIntDefaultNumberOfBits = value;
 
99
}
 
100
 
 
101
unsigned long GmpInt::getDefaultNumberOfBits()
 
102
{
 
103
    return gIntDefaultNumberOfBits;
 
104
}
 
105
 
 
106
inline void GmpInt::copyIfShared()
 
107
{
 
108
    if(mData->mRefCount > 1)
 
109
    {
 
110
        --(mData->mRefCount);
 
111
        GmpIntData* oldData = mData;
 
112
        mData = gmpIntDataContainer().allocateGmpIntData(0, false);
 
113
        mpz_set(mData->mInteger, oldData->mInteger);
 
114
    }
 
115
}
 
116
 
 
117
 
 
118
//===========================================================================
 
119
// Constructors, destructor, assignment
 
120
//===========================================================================
 
121
GmpInt::GmpInt(DummyType):
 
122
    mData(gmpIntDataContainer().allocateGmpIntData(0, false))
 
123
{}
 
124
 
 
125
GmpInt::GmpInt()
 
126
{
 
127
    mData = gmpIntDataContainer().const_0();
 
128
    ++(mData->mRefCount);
 
129
}
 
130
 
 
131
GmpInt::GmpInt(long value)
 
132
{
 
133
    if(value == 0)
 
134
    {
 
135
        mData = gmpIntDataContainer().const_0();
 
136
        ++(mData->mRefCount);
 
137
    }
 
138
    else
 
139
    {
 
140
        mData = gmpIntDataContainer().allocateGmpIntData
 
141
            (gIntDefaultNumberOfBits, false);
 
142
        mpz_set_si(mData->mInteger, value);
 
143
    }
 
144
}
 
145
 
 
146
GmpInt::GmpInt(unsigned long value)
 
147
{
 
148
    if(value == 0)
 
149
    {
 
150
        mData = gmpIntDataContainer().const_0();
 
151
        ++(mData->mRefCount);
 
152
    }
 
153
    else
 
154
    {
 
155
        mData = gmpIntDataContainer().allocateGmpIntData
 
156
            (gIntDefaultNumberOfBits, false);
 
157
        mpz_set_ui(mData->mInteger, value);
 
158
    }
 
159
}
 
160
 
 
161
GmpInt::GmpInt(int value)
 
162
{
 
163
    if(value == 0)
 
164
    {
 
165
        mData = gmpIntDataContainer().const_0();
 
166
        ++(mData->mRefCount);
 
167
    }
 
168
    else
 
169
    {
 
170
        mData = gmpIntDataContainer().allocateGmpIntData
 
171
            (gIntDefaultNumberOfBits, false);
 
172
        mpz_set_si(mData->mInteger, value);
 
173
    }
 
174
}
 
175
 
 
176
GmpInt::GmpInt(double value)
 
177
{
 
178
    const double absValue = value >= 0.0 ? value : -value;
 
179
    if(absValue < 1.0)
 
180
    {
 
181
        mData = gmpIntDataContainer().const_0();
 
182
        ++(mData->mRefCount);
 
183
    }
 
184
    else
 
185
    {
 
186
        mData = gmpIntDataContainer().allocateGmpIntData
 
187
            (gIntDefaultNumberOfBits, false);
 
188
        mpz_set_d(mData->mInteger, value);
 
189
    }
 
190
}
 
191
 
 
192
GmpInt::GmpInt(long double value)
 
193
{
 
194
    const long double absValue = value >= 0.0L ? value : -value;
 
195
    if(absValue < 1.0L)
 
196
    {
 
197
        mData = gmpIntDataContainer().const_0();
 
198
        ++(mData->mRefCount);
 
199
    }
 
200
    else
 
201
    {
 
202
        mData = gmpIntDataContainer().allocateGmpIntData
 
203
            (gIntDefaultNumberOfBits, false);
 
204
        mpz_set_d(mData->mInteger, double(value));
 
205
    }
 
206
}
 
207
 
 
208
GmpInt::GmpInt(const GmpInt& rhs):
 
209
    mData(rhs.mData)
 
210
{
 
211
    ++(mData->mRefCount);
 
212
}
 
213
 
 
214
GmpInt& GmpInt::operator=(const GmpInt& rhs)
 
215
{
 
216
    if(mData != rhs.mData)
 
217
    {
 
218
        gmpIntDataContainer().releaseGmpIntData(mData);
 
219
        mData = rhs.mData;
 
220
        ++(mData->mRefCount);
 
221
    }
 
222
    return *this;
 
223
}
 
224
 
 
225
GmpInt& GmpInt::operator=(signed long value)
 
226
{
 
227
    if(value == 0)
 
228
    {
 
229
        gmpIntDataContainer().releaseGmpIntData(mData);
 
230
        mData = gmpIntDataContainer().const_0();
 
231
        ++(mData->mRefCount);
 
232
    }
 
233
    else
 
234
    {
 
235
        if(mData->mRefCount > 1)
 
236
        {
 
237
            --(mData->mRefCount);
 
238
            mData = gmpIntDataContainer().allocateGmpIntData
 
239
                (gIntDefaultNumberOfBits, false);
 
240
        }
 
241
        mpz_set_si(mData->mInteger, value);
 
242
    }
 
243
    return *this;
 
244
}
 
245
 
 
246
GmpInt::~GmpInt()
 
247
{
 
248
    gmpIntDataContainer().releaseGmpIntData(mData);
 
249
}
 
250
 
 
251
 
 
252
//===========================================================================
 
253
// Data getters
 
254
//===========================================================================
 
255
template<>
 
256
void GmpInt::get_raw_mpfr_data<mpz_t>(mpz_t& dest_mpz_t)
 
257
{
 
258
    std::memcpy(&dest_mpz_t, mData->mInteger, sizeof(mpz_t));
 
259
}
 
260
 
 
261
const char* GmpInt::getAsString(int base) const
 
262
{
 
263
    intString().resize(mpz_sizeinbase(mData->mInteger, base) + 2);
 
264
    return mpz_get_str(&intString()[0], base, mData->mInteger);
 
265
}
 
266
 
 
267
long GmpInt::toInt() const
 
268
{
 
269
    return mpz_get_si(mData->mInteger);
 
270
}
 
271
 
 
272
 
 
273
//===========================================================================
 
274
// Modifying operators
 
275
//===========================================================================
 
276
GmpInt& GmpInt::operator+=(const GmpInt& rhs)
 
277
{
 
278
    copyIfShared();
 
279
    mpz_add(mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
280
    return *this;
 
281
}
 
282
 
 
283
GmpInt& GmpInt::operator+=(long value)
 
284
{
 
285
    copyIfShared();
 
286
    if(value >= 0)
 
287
        mpz_add_ui(mData->mInteger, mData->mInteger, value);
 
288
    else
 
289
        mpz_sub_ui(mData->mInteger, mData->mInteger, -value);
 
290
    return *this;
 
291
}
 
292
 
 
293
GmpInt& GmpInt::operator-=(const GmpInt& rhs)
 
294
{
 
295
    copyIfShared();
 
296
    mpz_sub(mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
297
    return *this;
 
298
}
 
299
 
 
300
GmpInt& GmpInt::operator-=(long value)
 
301
{
 
302
    copyIfShared();
 
303
    if(value >= 0)
 
304
        mpz_sub_ui(mData->mInteger, mData->mInteger, value);
 
305
    else
 
306
        mpz_add_ui(mData->mInteger, mData->mInteger, -value);
 
307
    return *this;
 
308
}
 
309
 
 
310
GmpInt& GmpInt::operator*=(const GmpInt& rhs)
 
311
{
 
312
    copyIfShared();
 
313
    mpz_mul(mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
314
    return *this;
 
315
}
 
316
 
 
317
GmpInt& GmpInt::operator*=(long value)
 
318
{
 
319
    copyIfShared();
 
320
    mpz_mul_si(mData->mInteger, mData->mInteger, value);
 
321
    return *this;
 
322
}
 
323
 
 
324
GmpInt& GmpInt::operator/=(const GmpInt& rhs)
 
325
{
 
326
    copyIfShared();
 
327
    mpz_tdiv_q(mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
328
    return *this;
 
329
}
 
330
 
 
331
GmpInt& GmpInt::operator/=(long value)
 
332
{
 
333
    copyIfShared();
 
334
    if(value >= 0)
 
335
        mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, value);
 
336
    else
 
337
    {
 
338
        mpz_neg(mData->mInteger, mData->mInteger);
 
339
        mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, -value);
 
340
    }
 
341
    return *this;
 
342
}
 
343
 
 
344
GmpInt& GmpInt::operator%=(const GmpInt& rhs)
 
345
{
 
346
    copyIfShared();
 
347
    if(operator<(0))
 
348
    {
 
349
        negate();
 
350
        mpz_mod(mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
351
        negate();
 
352
    }
 
353
    else
 
354
    {
 
355
        mpz_mod(mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
356
    }
 
357
    return *this;
 
358
}
 
359
 
 
360
GmpInt& GmpInt::operator%=(long value)
 
361
{
 
362
    copyIfShared();
 
363
    if(value < 0) value = -value;
 
364
    if(operator<(0))
 
365
    {
 
366
        negate();
 
367
        mpz_mod_ui(mData->mInteger, mData->mInteger, value);
 
368
        negate();
 
369
    }
 
370
    else
 
371
    {
 
372
        mpz_mod_ui(mData->mInteger, mData->mInteger, value);
 
373
    }
 
374
    return *this;
 
375
}
 
376
 
 
377
GmpInt& GmpInt::operator<<=(unsigned long bits)
 
378
{
 
379
    copyIfShared();
 
380
    mpz_mul_2exp(mData->mInteger, mData->mInteger, bits);
 
381
    return *this;
 
382
}
 
383
 
 
384
GmpInt& GmpInt::operator>>=(unsigned long bits)
 
385
{
 
386
    copyIfShared();
 
387
    mpz_tdiv_q_2exp(mData->mInteger, mData->mInteger, bits);
 
388
    return *this;
 
389
}
 
390
 
 
391
 
 
392
//===========================================================================
 
393
// Modifying functions
 
394
//===========================================================================
 
395
void GmpInt::addProduct(const GmpInt& value1, const GmpInt& value2)
 
396
{
 
397
    copyIfShared();
 
398
    mpz_addmul(mData->mInteger, value1.mData->mInteger, value2.mData->mInteger);
 
399
}
 
400
 
 
401
void GmpInt::addProduct(const GmpInt& value1, unsigned long value2)
 
402
{
 
403
    copyIfShared();
 
404
    mpz_addmul_ui(mData->mInteger, value1.mData->mInteger, value2);
 
405
}
 
406
 
 
407
void GmpInt::subProduct(const GmpInt& value1, const GmpInt& value2)
 
408
{
 
409
    copyIfShared();
 
410
    mpz_submul(mData->mInteger, value1.mData->mInteger, value2.mData->mInteger);
 
411
}
 
412
 
 
413
void GmpInt::subProduct(const GmpInt& value1, unsigned long value2)
 
414
{
 
415
    copyIfShared();
 
416
    mpz_submul_ui(mData->mInteger, value1.mData->mInteger, value2);
 
417
}
 
418
 
 
419
void GmpInt::negate()
 
420
{
 
421
    copyIfShared();
 
422
    mpz_neg(mData->mInteger, mData->mInteger);
 
423
}
 
424
 
 
425
void GmpInt::abs()
 
426
{
 
427
    copyIfShared();
 
428
    mpz_abs(mData->mInteger, mData->mInteger);
 
429
}
 
430
 
 
431
GmpInt GmpInt::abs(const GmpInt& value)
 
432
{
 
433
    GmpInt retval(kNoInitialization);
 
434
    mpz_abs(retval.mData->mInteger, value.mData->mInteger);
 
435
    return retval;
 
436
}
 
437
 
 
438
 
 
439
//===========================================================================
 
440
// Non-modifying operators
 
441
//===========================================================================
 
442
GmpInt GmpInt::operator+(const GmpInt& rhs) const
 
443
{
 
444
    GmpInt retval(kNoInitialization);
 
445
    mpz_add(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
446
    return retval;
 
447
}
 
448
 
 
449
GmpInt GmpInt::operator+(long value) const
 
450
{
 
451
    GmpInt retval(kNoInitialization);
 
452
    if(value >= 0)
 
453
        mpz_add_ui(retval.mData->mInteger, mData->mInteger, value);
 
454
    else
 
455
        mpz_sub_ui(retval.mData->mInteger, mData->mInteger, -value);
 
456
    return retval;
 
457
}
 
458
 
 
459
GmpInt GmpInt::operator-(const GmpInt& rhs) const
 
460
{
 
461
    GmpInt retval(kNoInitialization);
 
462
    mpz_sub(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
463
    return retval;
 
464
}
 
465
 
 
466
GmpInt GmpInt::operator-(long value) const
 
467
{
 
468
    GmpInt retval(kNoInitialization);
 
469
    if(value >= 0)
 
470
        mpz_sub_ui(retval.mData->mInteger, mData->mInteger, value);
 
471
    else
 
472
        mpz_add_ui(retval.mData->mInteger, mData->mInteger, -value);
 
473
    return retval;
 
474
}
 
475
 
 
476
GmpInt GmpInt::operator*(const GmpInt& rhs) const
 
477
{
 
478
    GmpInt retval(kNoInitialization);
 
479
    mpz_mul(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
480
    return retval;
 
481
}
 
482
 
 
483
GmpInt GmpInt::operator*(long value) const
 
484
{
 
485
    GmpInt retval(kNoInitialization);
 
486
    mpz_mul_si(retval.mData->mInteger, mData->mInteger, value);
 
487
    return retval;
 
488
}
 
489
 
 
490
GmpInt GmpInt::operator/(const GmpInt& rhs) const
 
491
{
 
492
    GmpInt retval(kNoInitialization);
 
493
    mpz_tdiv_q(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
494
    return retval;
 
495
}
 
496
 
 
497
GmpInt GmpInt::operator/(long value) const
 
498
{
 
499
    GmpInt retval(kNoInitialization);
 
500
    if(value >= 0)
 
501
        mpz_tdiv_q_ui(retval.mData->mInteger, mData->mInteger, value);
 
502
    else
 
503
    {
 
504
        mpz_neg(retval.mData->mInteger, mData->mInteger);
 
505
        mpz_tdiv_q_ui(retval.mData->mInteger, retval.mData->mInteger, -value);
 
506
    }
 
507
    return retval;
 
508
}
 
509
 
 
510
GmpInt GmpInt::operator%(const GmpInt& rhs) const
 
511
{
 
512
    GmpInt retval(kNoInitialization);
 
513
    if(operator<(0))
 
514
    {
 
515
        mpz_neg(retval.mData->mInteger, mData->mInteger);
 
516
        mpz_mod(retval.mData->mInteger,
 
517
                retval.mData->mInteger, rhs.mData->mInteger);
 
518
        retval.negate();
 
519
    }
 
520
    else
 
521
    {
 
522
        mpz_mod(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger);
 
523
    }
 
524
    return retval;
 
525
}
 
526
 
 
527
GmpInt GmpInt::operator%(long value) const
 
528
{
 
529
    GmpInt retval(kNoInitialization);
 
530
    if(value < 0) value = -value;
 
531
    if(operator<(0))
 
532
    {
 
533
        mpz_neg(retval.mData->mInteger, mData->mInteger);
 
534
        mpz_mod_ui(retval.mData->mInteger, retval.mData->mInteger, value);
 
535
        retval.negate();
 
536
    }
 
537
    else
 
538
    {
 
539
        mpz_mod_ui(retval.mData->mInteger, mData->mInteger, value);
 
540
    }
 
541
    return retval;
 
542
}
 
543
 
 
544
GmpInt GmpInt::operator-() const
 
545
{
 
546
    GmpInt retval(kNoInitialization);
 
547
    mpz_neg(retval.mData->mInteger, mData->mInteger);
 
548
    return retval;
 
549
}
 
550
 
 
551
GmpInt GmpInt::operator<<(unsigned long bits) const
 
552
{
 
553
    GmpInt retval(kNoInitialization);
 
554
    mpz_mul_2exp(retval.mData->mInteger, mData->mInteger, bits);
 
555
    return retval;
 
556
}
 
557
 
 
558
GmpInt GmpInt::operator>>(unsigned long bits) const
 
559
{
 
560
    GmpInt retval(kNoInitialization);
 
561
    mpz_tdiv_q_2exp(retval.mData->mInteger, mData->mInteger, bits);
 
562
    return retval;
 
563
}
 
564
 
 
565
 
 
566
//===========================================================================
 
567
// Comparison operators
 
568
//===========================================================================
 
569
bool GmpInt::operator<(const GmpInt& rhs) const
 
570
{
 
571
    return mpz_cmp(mData->mInteger, rhs.mData->mInteger) < 0;
 
572
}
 
573
 
 
574
bool GmpInt::operator<(long value) const
 
575
{
 
576
    return mpz_cmp_si(mData->mInteger, value) < 0;
 
577
}
 
578
 
 
579
bool GmpInt::operator<=(const GmpInt& rhs) const
 
580
{
 
581
    return mpz_cmp(mData->mInteger, rhs.mData->mInteger) <= 0;
 
582
}
 
583
 
 
584
bool GmpInt::operator<=(long value) const
 
585
{
 
586
    return mpz_cmp_si(mData->mInteger, value) <= 0;
 
587
}
 
588
 
 
589
bool GmpInt::operator>(const GmpInt& rhs) const
 
590
{
 
591
    return mpz_cmp(mData->mInteger, rhs.mData->mInteger) > 0;
 
592
}
 
593
 
 
594
bool GmpInt::operator>(long value) const
 
595
{
 
596
    return mpz_cmp_si(mData->mInteger, value) > 0;
 
597
}
 
598
 
 
599
bool GmpInt::operator>=(const GmpInt& rhs) const
 
600
{
 
601
    return mpz_cmp(mData->mInteger, rhs.mData->mInteger) >= 0;
 
602
}
 
603
 
 
604
bool GmpInt::operator>=(long value) const
 
605
{
 
606
    return mpz_cmp_si(mData->mInteger, value) >= 0;
 
607
}
 
608
 
 
609
bool GmpInt::operator==(const GmpInt& rhs) const
 
610
{
 
611
    return mpz_cmp(mData->mInteger, rhs.mData->mInteger) == 0;
 
612
}
 
613
 
 
614
bool GmpInt::operator==(long value) const
 
615
{
 
616
    return mpz_cmp_si(mData->mInteger, value) == 0;
 
617
}
 
618
 
 
619
bool GmpInt::operator!=(const GmpInt& rhs) const
 
620
{
 
621
    return mpz_cmp(mData->mInteger, rhs.mData->mInteger) != 0;
 
622
}
 
623
 
 
624
bool GmpInt::operator!=(long value) const
 
625
{
 
626
    return mpz_cmp_si(mData->mInteger, value) != 0;
 
627
}
 
628
 
 
629
void GmpInt::parseValue(const char* value)
 
630
{
 
631
    mpz_set_str(mData->mInteger, value, 10);
 
632
}
 
633
 
 
634
void GmpInt::parseValue(const char* value, char** endptr)
 
635
{
 
636
    static std::vector<char> str;
 
637
 
 
638
    unsigned startIndex = 0;
 
639
    while(value[startIndex] && std::isspace(value[startIndex])) ++startIndex;
 
640
    if(!value[startIndex]) { *endptr = const_cast<char*>(value); return; }
 
641
 
 
642
    unsigned endIndex = startIndex;
 
643
    if(value[endIndex] == '-') ++endIndex;
 
644
    if(!std::isdigit(value[endIndex]))
 
645
    { *endptr = const_cast<char*>(value); return; }
 
646
    if(value[endIndex] == '0' && value[endIndex+1] == 'x')
 
647
    {
 
648
        endIndex += 1;
 
649
        while(std::isxdigit(value[++endIndex])) {}
 
650
    }
 
651
    else
 
652
    {
 
653
        while(std::isdigit(value[++endIndex])) {}
 
654
    }
 
655
 
 
656
    str.reserve(endIndex - startIndex + 1);
 
657
    str.assign(value + startIndex, value + endIndex);
 
658
    str.push_back(0);
 
659
 
 
660
    mpz_set_str(mData->mInteger, &str[0], 0);
 
661
    *endptr = const_cast<char*>(value + endIndex);
 
662
}
 
663
 
 
664
GmpInt GmpInt::parseString(const char* str, char** endptr)
 
665
{
 
666
    GmpInt retval(kNoInitialization);
 
667
    retval.parseValue(str, endptr);
 
668
    return retval;
 
669
}
 
670
 
 
671
//===========================================================================
 
672
// Operator functions
 
673
//===========================================================================
 
674
GmpInt operator+(long lhs, const GmpInt& rhs)
 
675
{
 
676
    GmpInt retval(GmpInt::kNoInitialization);
 
677
    if(lhs >= 0)
 
678
        mpz_add_ui(retval.mData->mInteger, rhs.mData->mInteger, lhs);
 
679
    else
 
680
        mpz_sub_ui(retval.mData->mInteger, rhs.mData->mInteger, -lhs);
 
681
    return retval;
 
682
}
 
683
 
 
684
GmpInt operator-(long lhs, const GmpInt& rhs)
 
685
{
 
686
    GmpInt retval(GmpInt::kNoInitialization);
 
687
    if(lhs >= 0)
 
688
        mpz_ui_sub(retval.mData->mInteger, lhs, rhs.mData->mInteger);
 
689
    else
 
690
    {
 
691
        mpz_add_ui(retval.mData->mInteger, rhs.mData->mInteger, -lhs);
 
692
        mpz_neg(retval.mData->mInteger, retval.mData->mInteger);
 
693
    }
 
694
    return retval;
 
695
}
 
696
 
 
697
GmpInt operator*(long lhs, const GmpInt& rhs)
 
698
{
 
699
    return rhs * lhs;
 
700
}
 
701
 
 
702
GmpInt operator/(long lhs, const GmpInt& rhs)
 
703
{
 
704
    return GmpInt(lhs) / rhs;
 
705
}
 
706
 
 
707
GmpInt operator%(long lhs, const GmpInt& rhs)
 
708
{
 
709
    return GmpInt(lhs) % rhs;
 
710
}