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

12
src/h.h
View File

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