usz multiplication
This commit is contained in:
parent
4299fef6b6
commit
cec962fb8c
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
12
src/h.h
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user