diff --git a/.ic3_history b/.ic3_history
index 3db3844..b497a8a 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,8 +1,3 @@
-1/2 + 2/3
-1/2 * 2/3
-1/2 / 2/3
-1/2 / 3/2
-1/2 + 2/3
3/2 + 2/3
3/2 + 4/3
1/2 + 4/3
@@ -97,3 +92,8 @@ sqrt(-2) * sqrt(-2)
1 +i 2
1/2 +i 2/3
(1/2 +i 2/3 +i 3/4) * 1/2
+(1/2 +i 2/3 +i 3/4) - 1/2
+1 - 1/2
+1/2 - 1
+1/2 - 3/4
+1 - 3/4
diff --git a/libc3/tag_sub.c b/libc3/tag_sub.c
index 7ef3746..2598967 100644
--- a/libc3/tag_sub.c
+++ b/libc3/tag_sub.c
@@ -27,15 +27,110 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
assert(b);
assert(dest);
switch (a->type) {
+ case TAG_COMPLEX:
+ switch (b->type) {
+ case TAG_COMPLEX:
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ b->data.complex));
+ case TAG_F32:
+ complex_init_f32(&c, b->data.f32);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_F64:
+ complex_init_f64(&c, b->data.f64);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_F128:
+ complex_init_f128(&c, b->data.f128);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_INTEGER:
+ if (! complex_init_integer(&c, &b->data.integer))
+ return NULL;
+ if (! tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c))) {
+
+ complex_clean(&c);
+ return NULL;
+ }
+ complex_clean(&c);
+ return dest;
+ case TAG_RATIO:
+ if (! complex_init_ratio(&c, &b->data.ratio))
+ return NULL;
+ if (! tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c))) {
+
+ complex_clean(&c);
+ return NULL;
+ }
+ complex_clean(&c);
+ return dest;
+ case TAG_S8:
+ complex_init_s8(&c, b->data.s8);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_S16:
+ complex_init_s16(&c, b->data.s16);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_S32:
+ complex_init_s32(&c, b->data.s32);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_S64:
+ complex_init_s64(&c, b->data.s64);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_SW:
+ complex_init_sw(&c, b->data.sw);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_U8:
+ complex_init_u8(&c, b->data.u8);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_U16:
+ complex_init_u16(&c, b->data.u16);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_U32:
+ complex_init_u32(&c, b->data.u32);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_U64:
+ complex_init_u64(&c, b->data.u64);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ case TAG_UW:
+ complex_init_uw(&c, b->data.uw);
+ return tag_init_complex(dest, complex_new_sub(a->data.complex,
+ &c));
+ default:
+ break;
+ }
+ break;
case TAG_F32:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_f32(&c, a->data.f32);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
return tag_init_f32(dest, a->data.f32 - b->data.f32);
case TAG_F64:
- return tag_init_f64(dest, a->data.f32 - b->data.f64);
+ return tag_init_f64(dest, (f64) a->data.f32 - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.f32 - b->data.f128);
case TAG_INTEGER:
return tag_init_f32(dest, a->data.f32 -
integer_to_f32(&b->data.integer));
+ case TAG_RATIO:
+ ratio_init_f32(&r, a->data.f32);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
return tag_init_f32(dest, a->data.f32 - b->data.s8);
case TAG_S16:
@@ -44,6 +139,8 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
return tag_init_f32(dest, a->data.f32 - b->data.s32);
case TAG_S64:
return tag_init_f32(dest, a->data.f32 - b->data.s64);
+ case TAG_SW:
+ return tag_init_f32(dest, a->data.f32 - (f32) b->data.sw);
case TAG_U8:
return tag_init_f32(dest, a->data.f32 - b->data.u8);
case TAG_U16:
@@ -52,18 +149,32 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
return tag_init_f32(dest, a->data.f32 - b->data.u32);
case TAG_U64:
return tag_init_f32(dest, a->data.f32 - b->data.u64);
+ case TAG_UW:
+ return tag_init_f32(dest, a->data.f32 - (f32) b->data.uw);
default:
goto ko;
}
case TAG_F64:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_f64(&c, a->data.f64);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
- return tag_init_f64(dest, a->data.f64 - b->data.f32);
+ return tag_init_f64(dest, a->data.f64 - (f64) b->data.f32);
case TAG_F64:
return tag_init_f64(dest, a->data.f64 - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.f64 - b->data.f128);
case TAG_INTEGER:
return tag_init_f64(dest, a->data.f64 -
integer_to_f64(&b->data.integer));
+ case TAG_RATIO:
+ ratio_init_f64(&r, a->data.f64);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
return tag_init_f64(dest, a->data.f64 - b->data.s8);
case TAG_S16:
@@ -72,6 +183,8 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
return tag_init_f64(dest, a->data.f64 - b->data.s32);
case TAG_S64:
return tag_init_f64(dest, a->data.f64 - b->data.s64);
+ case TAG_SW:
+ return tag_init_f64(dest, a->data.f64 - (f64) b->data.sw);
case TAG_U8:
return tag_init_f64(dest, a->data.f64 - b->data.u8);
case TAG_U16:
@@ -80,22 +193,87 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
return tag_init_f64(dest, a->data.f64 - b->data.u32);
case TAG_U64:
return tag_init_f64(dest, a->data.f64 - b->data.u64);
+ case TAG_UW:
+ return tag_init_f64(dest, a->data.f64 - (f64) b->data.uw);
+ default:
+ goto ko;
+ }
+ case TAG_F128:
+ switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_f128(&c, a->data.f128);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
+ case TAG_F32:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.f32);
+ case TAG_F64:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, a->data.f128 - b->data.f128);
+ case TAG_INTEGER:
+ return tag_init_f128(dest, a->data.f128 -
+ integer_to_f128(&a->data.integer));
+ case TAG_RATIO:
+ ratio_init_f128(&r, a->data.f128);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
+ case TAG_S8:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.s8);
+ case TAG_S16:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.s16);
+ case TAG_S32:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.s32);
+ case TAG_S64:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.s64);
+ case TAG_SW:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.sw);
+ case TAG_U8:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.u8);
+ case TAG_U16:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.u16);
+ case TAG_U32:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.u32);
+ case TAG_U64:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.u64);
+ case TAG_UW:
+ return tag_init_f128(dest, a->data.f128 - (f128) b->data.uw);
default:
goto ko;
}
case TAG_INTEGER:
switch (b->type) {
+ case TAG_COMPLEX:
+ if (! complex_init_integer(&c, &a->data.integer))
+ return NULL;
+ if (! tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex))) {
+ complex_clean(&c);
+ return NULL;
+ }
+ complex_clean(&c);
+ return dest;
case TAG_F32:
return tag_init_f32(dest, integer_to_f64(&a->data.integer) -
b->data.f32);
case TAG_F64:
return tag_init_f64(dest, integer_to_f64(&a->data.integer) -
b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, integer_to_f128(&a->data.integer) -
+ b->data.f128);
case TAG_INTEGER:
dest->type = TAG_INTEGER;
integer_sub(&a->data.integer, &b->data.integer,
&dest->data.integer);
return dest;
+ case TAG_RATIO:
+ ratio_init_integer(&r, &a->data.integer);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
integer_init_s8(&tmp, b->data.s8);
dest->type = TAG_INTEGER;
@@ -120,6 +298,12 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_sub(&a->data.integer, &tmp, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_SW:
+ integer_init_sw(&tmp, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&a->data.integer, &tmp, &dest->data.integer);
+ integer_clean(&tmp);
+ return dest;
case TAG_U8:
integer_init_u8(&tmp, b->data.u8);
dest->type = TAG_INTEGER;
@@ -144,6 +328,12 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_sub(&a->data.integer, &tmp, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_UW:
+ integer_init_uw(&tmp, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&a->data.integer, &tmp, &dest->data.integer);
+ integer_clean(&tmp);
+ return dest;
default:
goto ko;
}
@@ -254,16 +444,28 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
}
case TAG_S8:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_s8(&c, a->data.s8);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
- return tag_init_f32(dest, a->data.s8 - b->data.f32);
+ return tag_init_f32(dest, (f32) a->data.s8 - b->data.f32);
case TAG_F64:
- return tag_init_f64(dest, a->data.s8 - b->data.f64);
+ return tag_init_f64(dest, (f64) a->data.s8 - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.s8 - b->data.f128);
case TAG_INTEGER:
integer_init_s8(&tmp, a->data.s8);
dest->type = TAG_INTEGER;
integer_sub(&tmp, &b->data.integer, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_RATIO:
+ ratio_init_s8(&r, a->data.s8);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
return tag_init_s16(dest, (s16) a->data.s8 - (s16) b->data.s8);
case TAG_S16:
@@ -278,6 +480,14 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_SW:
+ integer_init_s8(&tmp, a->data.s8);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
return tag_init_s16(dest, (s16) a->data.s8 - (s16) b->data.u8);
case TAG_U16:
@@ -292,21 +502,41 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_UW:
+ integer_init_s8(&tmp, a->data.s8);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
case TAG_S16:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_s16(&c, a->data.s16);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
- return tag_init_f32(dest, a->data.s16 - b->data.f32);
+ return tag_init_f32(dest, (f32) a->data.s16 - b->data.f32);
case TAG_F64:
- return tag_init_f64(dest, a->data.s16 - b->data.f64);
+ return tag_init_f64(dest, (f64) a->data.s16 - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.s16 - b->data.f128);
case TAG_INTEGER:
integer_init_s16(&tmp, a->data.s16);
dest->type = TAG_INTEGER;
integer_sub(&tmp, &b->data.integer, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_RATIO:
+ ratio_init_s16(&r, a->data.s16);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
return tag_init_s16(dest, a->data.s16 - b->data.s8);
case TAG_S16:
@@ -320,6 +550,14 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_sub(&tmp, &tmp2, &dest->data.integer);
integer_clean(&tmp);
integer_clean(&tmp2);
+ return dest;
+ case TAG_SW:
+ integer_init_s16(&tmp, a->data.s16);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
return dest;
case TAG_U8:
return tag_init_s32(dest, (s32) a->data.s16 - (s32) b->data.u8);
@@ -335,21 +573,41 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_UW:
+ integer_init_s16(&tmp, a->data.s16);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
case TAG_S32:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_s32(&c, a->data.s32);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
return tag_init_f32(dest, a->data.s32 - b->data.f32);
case TAG_F64:
return tag_init_f64(dest, a->data.s32 - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.s32 - b->data.f128);
case TAG_INTEGER:
integer_init_s32(&tmp, a->data.s32);
dest->type = TAG_INTEGER;
integer_sub(&tmp, &b->data.integer, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_RATIO:
+ ratio_init_s32(&r, a->data.s32);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
return tag_init_s64(dest, (s64) a->data.s32 - (s64) b->data.s8);
case TAG_S16:
@@ -364,6 +622,14 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_SW:
+ integer_init_s32(&tmp, a->data.s32);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
return tag_init_s64(dest, (s64) a->data.s32 - (s64) b->data.u8);
case TAG_U16:
@@ -378,21 +644,41 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_UW:
+ integer_init_s32(&tmp, a->data.s32);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
case TAG_S64:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_s64(&c, a->data.s64);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
return tag_init_f32(dest, a->data.s64 - b->data.f32);
case TAG_F64:
return tag_init_f64(dest, a->data.s64 - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.s64 - b->data.f128);
case TAG_INTEGER:
integer_init_s64(&tmp, a->data.s64);
dest->type = TAG_INTEGER;
integer_sub(&tmp, &b->data.integer, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_RATIO:
+ ratio_init_s64(&r, a->data.s64);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
integer_init_s64(&tmp, a->data.s64);
integer_init_s8(&tmp2, b->data.s8);
@@ -425,6 +711,14 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_SW:
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
integer_init_s64(&tmp, a->data.s64);
integer_init_u8(&tmp2, b->data.u8);
@@ -457,21 +751,148 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_UW:
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ default:
+ goto ko;
+ }
+ case TAG_SW:
+ switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_sw(&c, a->data.sw);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
+ case TAG_F32:
+ return tag_init_f32(dest, (f32) a->data.sw - b->data.f32);
+ case TAG_F64:
+ return tag_init_f64(dest, (f64) a->data.sw - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.sw - b->data.f128);
+ case TAG_INTEGER:
+ integer_init_sw(&tmp, a->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &b->data.integer, &dest->data.integer);
+ integer_clean(&tmp);
+ return dest;
+ case TAG_RATIO:
+ ratio_init_sw(&r, a->data.sw);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
+ case TAG_S8:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_s8(&tmp2, b->data.s8);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_S16:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_s16(&tmp2, b->data.s16);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_S32:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_s32(&tmp2, b->data.s32);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_S64:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_s64(&tmp2, b->data.s64);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_SW:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_U8:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_u8(&tmp2, b->data.u8);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_U16:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_u16(&tmp2, b->data.u16);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_U32:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_u32(&tmp2, b->data.u32);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_U64:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_u64(&tmp2, b->data.u64);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_UW:
+ integer_init_sw(&tmp, a->data.sw);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
case TAG_U8:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_u8(&c, a->data.u8);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
return tag_init_f32(dest, a->data.u8 - b->data.f32);
case TAG_F64:
return tag_init_f64(dest, a->data.u8 - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.u8 - b->data.f128);
case TAG_INTEGER:
integer_init_u8(&tmp, a->data.u8);
dest->type = TAG_INTEGER;
integer_sub(&tmp, &b->data.integer, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_RATIO:
+ ratio_init_u8(&r, a->data.u8);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
return tag_init_s16(dest, (s16) a->data.u8 - (s16) b->data.s8);
case TAG_S16:
@@ -486,6 +907,14 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_SW:
+ integer_init_u8(&tmp, a->data.u8);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
return tag_init_s16(dest, (s16) a->data.u8 - (s16) b->data.u8);
case TAG_U16:
@@ -500,11 +929,23 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_UW:
+ integer_init_u8(&tmp, a->data.u8);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
case TAG_U16:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_u16(&c, a->data.u16);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
return tag_init_f32(dest, (f32) a->data.u16 - b->data.f32);
case TAG_F64:
@@ -517,6 +958,12 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_sub(&tmp, &b->data.integer, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_RATIO:
+ ratio_init_u16(&r, a->data.u16);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
return tag_init_s32(dest, (s32) a->data.u16 - (s32) b->data.s8);
case TAG_S16:
@@ -531,6 +978,14 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_SW:
+ integer_init_u16(&tmp, a->data.u16);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
return tag_init_s32(dest, (s32) a->data.u16 - (s32) b->data.u8);
case TAG_U16:
@@ -545,21 +1000,41 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_UW:
+ integer_init_u16(&tmp, a->data.u16);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
case TAG_U32:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_u32(&c, a->data.u32);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
return tag_init_f32(dest, a->data.u32 - b->data.f32);
case TAG_F64:
return tag_init_f64(dest, a->data.u32 - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.u32 - b->data.f128);
case TAG_INTEGER:
integer_init_u32(&tmp, a->data.u32);
dest->type = TAG_INTEGER;
integer_sub(&tmp, &b->data.integer, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_RATIO:
+ ratio_init_u32(&r, a->data.u32);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
return tag_init_s64(dest, (s64) a->data.u32 - (s64) b->data.s8);
case TAG_S16:
@@ -574,6 +1049,14 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_SW:
+ integer_init_u32(&tmp, a->data.u32);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
return tag_init_s64(dest, (s64) a->data.u32 - (s64) b->data.u8);
case TAG_U16:
@@ -588,21 +1071,41 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_UW:
+ integer_init_u32(&tmp, a->data.u32);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
case TAG_U64:
switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_u64(&c, a->data.u64);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
case TAG_F32:
return tag_init_f32(dest, a->data.u64 - b->data.f32);
case TAG_F64:
return tag_init_f64(dest, a->data.u64 - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.u64 - b->data.f128);
case TAG_INTEGER:
integer_init_u64(&tmp, a->data.u64);
dest->type = TAG_INTEGER;
integer_sub(&tmp, &b->data.integer, &dest->data.integer);
integer_clean(&tmp);
return dest;
+ case TAG_RATIO:
+ ratio_init_u64(&r, a->data.u64);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
case TAG_S8:
integer_init_u64(&tmp, a->data.u64);
integer_init_s8(&tmp2, b->data.s8);
@@ -635,6 +1138,14 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_SW:
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
integer_init_u64(&tmp, a->data.u64);
integer_init_u8(&tmp2, b->data.u8);
@@ -667,6 +1178,121 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
integer_clean(&tmp2);
return dest;
+ case TAG_UW:
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ default:
+ goto ko;
+ }
+ case TAG_UW:
+ switch (b->type) {
+ case TAG_COMPLEX:
+ complex_init_uw(&c, a->data.uw);
+ return tag_init_complex(dest, complex_new_sub(&c,
+ b->data.complex));
+ case TAG_F32:
+ return tag_init_f32(dest, (f32) a->data.uw - b->data.f32);
+ case TAG_F64:
+ return tag_init_f64(dest, (f64) a->data.uw - b->data.f64);
+ case TAG_F128:
+ return tag_init_f128(dest, (f128) a->data.uw - b->data.f128);
+ case TAG_INTEGER:
+ integer_init_uw(&tmp, a->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &b->data.integer, &dest->data.integer);
+ integer_clean(&tmp);
+ return dest;
+ case TAG_RATIO:
+ ratio_init_uw(&r, a->data.uw);
+ dest->type = TAG_RATIO;
+ ratio_sub(&r, &b->data.ratio, &dest->data.ratio);
+ ratio_clean(&r);
+ return dest;
+ case TAG_S8:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_s8(&tmp2, b->data.s8);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_S16:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_s16(&tmp2, b->data.s16);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_S32:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_s32(&tmp2, b->data.s32);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_S64:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_s64(&tmp2, b->data.s64);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_SW:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_sw(&tmp2, b->data.sw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_U8:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_u8(&tmp2, b->data.u8);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_U16:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_u16(&tmp2, b->data.u16);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_U32:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_u32(&tmp2, b->data.u32);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_U64:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_u64(&tmp2, b->data.u64);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ case TAG_UW:
+ integer_init_uw(&tmp, a->data.uw);
+ integer_init_uw(&tmp2, b->data.uw);
+ dest->type = TAG_INTEGER;
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
@@ -674,9 +1300,9 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
goto ko;
}
ko:
- err_write_1("tag_sub: cannot subtract ");
+ err_write_1("tag_sub: invalid tag type: ");
err_write_1(tag_type_to_string(a->type));
- err_write_1(" by ");
+ err_write_1(" - ");
err_puts(tag_type_to_string(b->type));
return NULL;
}