summaryrefslogtreecommitdiff
path: root/MLKInteger.m
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-07-29 19:56:21 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-07-29 19:56:21 +0200
commit9c3236394224167b31eeb402fa78928a0e3eb7fe (patch)
treedc76fdd35091dba953e62e1d737701292bb6f26d /MLKInteger.m
parent5df0d8d27dae228d9568de691ca434194170d1ac (diff)
Add a non-trivial number of arithmetic methods to number classes.
Diffstat (limited to 'MLKInteger.m')
-rw-r--r--MLKInteger.m80
1 files changed, 80 insertions, 0 deletions
diff --git a/MLKInteger.m b/MLKInteger.m
index 345235a..c2a3f92 100644
--- a/MLKInteger.m
+++ b/MLKInteger.m
@@ -83,11 +83,91 @@ DEFINE_MPZ_TWOARG_OPERATION (multiplyWith:, mpz_mul)
DEFINE_MPZ_TWOARG_OPERATION (divideBy:, mpz_div)
+#define DEFINE_MPZ_TWOARG_INTONLY_OPERATION(SELECTOR, GMPFUN) \
+ DEFINE_GMP_OPERATION (SELECTOR (MLKInteger *)arg, \
+ mpz, \
+ GMPFUN (mpval, self->value, ((MLKInteger*)arg)->value), \
+ MLKInteger, \
+ MLKInteger, \
+ integerWithMPZ:)
+
+DEFINE_MPZ_TWOARG_INTONLY_OPERATION (mod:, mpz_mod)
+DEFINE_MPZ_TWOARG_INTONLY_OPERATION (exactlyDivideBy:, mpz_divexact)
+DEFINE_MPZ_TWOARG_INTONLY_OPERATION (gcd:, mpz_gcd)
+DEFINE_MPZ_TWOARG_INTONLY_OPERATION (lcm:, mpz_lcm)
+
+
+-(MLKInteger *) pow:(MLKInteger *)exponent
+{
+ mpz_t mpz;
+ mpz_t i;
+
+ mpz_init_set_ui (mpz, 1);
+ mpz_init_set (i, exponent->value);
+
+ while (mpz_sgn (i) > 0)
+ {
+ mpz_mul (mpz, mpz, self->value);
+ mpz_sub_ui (i, i, 1);
+ }
+
+ MLKInteger *obj = [MLKInteger integerWithMPZ:mpz];
+ mpz_clear (mpz);
+ mpz_clear (i);
+
+ return obj;
+}
+
+-(BOOL) evenp
+{
+ return mpz_even_p (self->value);
+}
+
+-(BOOL) oddp
+{
+ return mpz_odd_p (self->value);
+}
+
+-(MLKInteger *) isqrt
+{
+ mpz_t mpz;
+
+ mpz_init (mpz);
+ mpz_sqrt (mpz, self->value);
+ MLKInteger *obj = [MLKInteger integerWithMPZ:mpz];
+ mpz_clear (mpz);
+
+ return obj;
+}
+
-(int) intValue
{
return mpz_get_si (value);
}
+-(double) doubleValue
+{
+ return mpz_get_d (value);
+}
+
+-(NSComparisonResult) compare:(MLKInteger *)arg
+{
+ int cmp = mpz_cmp (self->value, arg->value);
+
+ if (cmp == 0)
+ return NSOrderedSame;
+ else if (cmp < 0)
+ return NSOrderedAscending;
+ else
+ return NSOrderedDescending;
+}
+
+-(BOOL) isEqual:(id)arg
+{
+ return ([arg isKindOfClass:[MLKInteger class]]
+ && [self compare:arg] == 0);
+}
+
-(NSString *) description
{
return [self descriptionWithBase:10];