usz multiplication

This commit is contained in:
dzaima 2021-09-05 21:51:00 +03:00
parent 4299fef6b6
commit cec962fb8c
4 changed files with 31 additions and 24 deletions

View File

@ -46,9 +46,9 @@ B tbl_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
if (EACH_FILLS) xf = getFillQ(x);
if (isAtm(w)) w = m_atomUnit(w);
if (isAtm(x)) x = m_atomUnit(x);
usz wia = a(w)->ia; ur wr = rnk(w);
usz xia = a(x)->ia; ur xr = rnk(x);
usz ria = wia*xia; ur rr = wr+xr;
ur wr = rnk(w); usz wia = a(w)->ia;
ur xr = rnk(x); usz xia = a(x)->ia;
ur rr = wr+xr; usz ria = uszMulT(wia, xia);
if (rr<xr) thrF("⌜: Result rank too large (%i≡=𝕨, %i≡=𝕩)", wr, xr);
BS2B wgetU = TI(w,getU);

View File

@ -60,7 +60,7 @@ B shape_c1(B t, B x) {
}
B shape_c2(B t, B w, B x) {
usz xia = isArr(x)? a(x)->ia : 1;
usz nia;
usz nia = 1;
ur nr;
ShArr* sh;
if (isF64(w)) {
@ -76,25 +76,25 @@ B shape_c2(B t, B w, B x) {
if (TI(w,elType)==el_i32) {
i32* wi = i32any_ptr(w);
if (nr>1) for (i32 i = 0; i < nr; i++) sh->a[i] = wi[i];
i64 tot = 1;
bool bad=false, good=false;
for (i32 i = 0; i < nr; i++) {
if (wi[i]<0) thrF("⥊: 𝕨 contained %i", wi[i]);
tot*= wi[i];
if (tot > USZ_MAX) thrM("⥊: Result too large"); // TODO this (& below) doesn't detect overflows for usz==u64
bad|= uszMul(&nia, wi[i]);
good|= wi[i]==0;
}
nia = (usz)tot;
if (bad && !good) thrM("⥊: 𝕨 too large");
} else {
BS2B getU = TI(w,getU);
i32 unkPos = -1;
i32 unkInd;
i64 tot = 1;
bool bad=false, good=false;
for (i32 i = 0; i < nr; i++) {
B c = getU(w, i);
if (isF64(c)) {
usz v = o2s(c);
if (sh) sh->a[i] = v;
tot*= v;
if (tot > USZ_MAX) thrM("⥊: Result too large");
bad|= uszMul(&nia, v);
good|= v==0;
} else {
if (isArr(c) || !isVal(c)) thrM("⥊: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑");
if (unkPos!=-1) thrM("⥊: 𝕨 contained multiple computed axes");
@ -102,11 +102,12 @@ B shape_c2(B t, B w, B x) {
unkInd = ((i32)v(c)->flags) - 1;
}
}
if (bad && !good) thrM("⥊: 𝕨 too large");
if (unkPos!=-1) {
if (unkInd!=52 & unkInd!=6 & unkInd!=30 & unkInd!=25) thrM("⥊: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑");
if (tot==0) thrM("⥊: Can't compute axis when the rest of the shape is empty");
i64 div = xia/tot;
i64 mod = xia%tot;
if (nia==0) thrM("⥊: Can't compute axis when the rest of the shape is empty");
i64 div = xia/nia;
i64 mod = xia%nia;
usz item;
bool fill = false;
if (unkInd == 52) {
@ -121,9 +122,7 @@ B shape_c2(B t, B w, B x) {
fill = true;
} else UD;
if (sh) sh->a[unkPos] = item;
tot*= item;
if (tot > USZ_MAX) thrM("⥊: Result too large");
nia = tot;
nia = uszMulT(nia, item);
if (fill) {
if (!isArr(x)) x = m_atomUnit(x);
Arr* a = take_impl(nia, x);
@ -131,7 +130,7 @@ B shape_c2(B t, B w, B x) {
x = taga(a);
xia = nia;
}
} else nia = tot;
}
}
}
dec(w);

View File

@ -93,6 +93,14 @@ static B m_v3(B a, B b, B c ); // consumes all
static B m_v4(B a, B b, B c, B d); // consumes all
static bool isNumEl(u8 elt) { return elt==el_i32 | elt==el_f64; }
static bool uszMul(usz* c, usz n) {
return __builtin_mul_overflow(*c, n, c);
}
static usz uszMulT(usz a, usz b) {
if (uszMul(&a, b)) thrM("Size too large");
return a;
}
// string stuff
B m_str8l(char* s);

12
src/h.h
View File

@ -100,12 +100,12 @@
#define i64 int64_t
#define u64 uint64_t
#define f64 double
#define I8_MAX 127
#define I16_MAX 65535
#define I8_MIN (-128)
#define I16_MIN (-65536)
#define I32_MAX ((i32)((1LL<<31)-1))
#define I32_MIN ((i32)(-(1LL<<31)))
#define I8_MIN -128
#define I8_MAX 127
#define I16_MIN -65536
#define I16_MAX 65535
#define I32_MIN -2147483648
#define I32_MAX 2147483647
#define I64_MIN ((i64)(1ULL<<63))
#define CHR_MAX 1114111
#define U16_MAX ((u16)~(u16)0)