fix 𝕨⍋𝕩 issues around NaNs

This commit is contained in:
dzaima 2025-02-01 20:55:04 +02:00
parent 9be5bf45b4
commit d506691690
4 changed files with 45 additions and 11 deletions

View File

@ -412,9 +412,13 @@ static u64 CAT(bit_boundary,GRADE_UD(up,dn))(u64* x, u64 n) {
}
#define LE_C2 CAT(GRADE_UD(le,ge),c2)
extern B LE_C2(B,B,B);
extern B select_c2(B t, B w, B x);
extern B mul_c2(B, B, B);
extern B lt_c2(B,B,B);
extern B le_c2(B,B,B);
extern B gt_c2(B,B,B);
extern B ge_c2(B,B,B);
extern B ne_c2(B,B,B);
extern B select_c2(B,B,B);
extern B mul_c2(B,B,B);
B GRADE_CAT(c2)(B t, B w, B x) {
if (isAtm(w) || RNK(w)==0) thrM(GRADE_CHR": 𝕨 must have rank≥1");
@ -442,6 +446,11 @@ B GRADE_CAT(c2)(B t, B w, B x) {
B c = IGet(w, 0);
if (LIKELY(we<el_B & xe<el_B)) {
decG(w);
if (we==el_f64 && elNum(xe) && q_nan(c)) return GRADE_UD(
C2(ne, incG(x), x),
i64EachDec(1, x)
);
if (GRADE_UD(1,0) && xe==el_f64) return bit_negate(C2(lt, x, c)); // handle NaNs in x properly
return LE_C2(m_f64(0), c, x);
} else {
SLOW2("𝕨"GRADE_CHR"𝕩", w, x); // Could narrow for mixed types
@ -493,6 +502,8 @@ B GRADE_CAT(c2)(B t, B w, B x) {
}
return r;
}
if (we==el_f64 && q_nan(IGetU(w,GRADE_UD(wia-1,0)))) goto gen;
#if SINGELI
#define WIDEN(E, X) switch (E) { default:UD; case el_i16:X=toI16Any(X);break; case el_i32:X=toI32Any(X);break; case el_f64:X=toF64Any(X);break; }
if (xe > we) {
@ -554,9 +565,7 @@ B GRADE_CAT(c2)(B t, B w, B x) {
}
#endif
} else {
#if !SINGELI
gen:;
#endif
i32* rp; r = m_i32arrc(&rp, x);
SLOW2("𝕨"GRADE_CHR"𝕩", w, x);
SGetU(w) SGetU(x)

View File

@ -24,6 +24,11 @@ static NOINLINE void generic_grade(B x, usz ia, B r, i32* rp, void (*fn)(BI32p*,
vfor (usz i = 0; i < ia; i++) rp[i] = tmp[i].v;
TFREE(tmp);
}
static bool q_nan(B x) {
assert(isNum(x));
double f = o2fG(x);
return f!=f;
}
#define GRADE_UD(U,D) U
#include "grade.h"

View File

@ -376,13 +376,13 @@ include './f64'
require{'math.h'}
fn saturate{F,T,...up}(dst:*void, src:*void, n:u64) : void = {
# Auto-vectorizes, although not that well for f64
def a = minvalue{T}; af := cast_i{F,a}
def b = maxvalue{T}; bf := cast_i{F,b}
def a = minvalue{T}
def b = maxvalue{T}
@for (d in *T~~dst, xf in *F~~src over n) {
x := if (F==f64) (if (select{up,0}) floor else ceil){xf} else xf
d = cast_i{T, x}
if (x<af) d = a
if (x>bf) d = b
if (not x<b) d = b
if (x<a) d = a
}
}

View File

@ -385,8 +385,28 @@ a←↕2 ⋄ ! "e" ≡ (↕10){b←a‿a‿a‿a‿a‿a‿a‿a‿a‿a ⋄
# 𝕨⍋𝕩
!"⍋: 𝕨 must be sorted" % a-¨ ¨ 10 a¨10
(¨)({! (𝕨𝕩) (𝕩) (𝕨)×0𝕨 •Cmp 𝕩}) 3, <3, 103, 'a', <'a', 10'a'
(¨)({! (𝕨𝕩) (𝕩) (𝕨)×0𝕨 •Cmp 𝕩}) 3, <3, 103, 'a', <'a', 10'a'
(¨)({𝕨𝕩! (𝕨𝕩) (𝕩) (𝕨)×0𝕨 •Cmp 𝕩}) 3, <3, 103, 'a', <'a', 10'a', 0÷0, 100÷0
(¨)({𝕨𝕩! (𝕨𝕩) (𝕩) (𝕨)×0𝕨 •Cmp 𝕩}) 3, <3, 103, 'a', <'a', 10'a', 0÷0, 100÷0
0 0,0÷0 %% 11
0÷0 ¯1÷0,¯3,0,1,2,1÷0,0÷0 %% 0000001
0,1 0,0÷0 %% 12
0,1,0÷0 0,0÷0 %% 13
0,0÷0 0,0÷0 %% 12
(100/0,0÷0) 0,0÷0 %% 100200
(¯5+10) 0,0÷0 %% 610
(¯5+10) 100,0÷0 %% 10610
((5)1000÷0) 10 %% 51+10
# 𝕨⍒𝕩
0 0,0÷0 %% 10
0÷0 ¯1÷0,¯3,0,1,2,1÷0,0÷0 %% 1111111
1,0 0,0÷0 %% 20
0÷0,1,0 0,0÷0 %% 31
0÷0,0 0,0÷0 %% 21
(100/0÷0,0) 0,0÷0 %% 200100
(5-10) 0,0÷0 %% 60
(5-10) 100,0÷0 %% 1060
((5)1000÷0) 10 %% 105-510
# ∧𝕩, 𝕩
"abc"3 %% (3)"abc"