fix eequal on different NaN patterns
+ rename compareFloat→floatCompare to be more consistent
This commit is contained in:
parent
a7897ddcde
commit
2a57cb30b8
@ -75,7 +75,7 @@ NOINLINE bool atomEqualF(B w, B x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool atomEEqual(B w, B x) { // doesn't consume
|
bool atomEEqual(B w, B x) { // doesn't consume
|
||||||
if (isF64(w) & isF64(x)) return w.f==x.f;
|
if (isF64(w) & isF64(x)) return floatIndistinguishable(w.f, x.f);
|
||||||
if (!isVal(w) || !isVal(x)) return false;
|
if (!isVal(w) || !isVal(x)) return false;
|
||||||
|
|
||||||
if (TI(w,byRef) || TY(w)!=TY(x)) return false;
|
if (TI(w,byRef) || TY(w)!=TY(x)) return false;
|
||||||
|
|||||||
@ -315,8 +315,10 @@ void noop_visit(Value* x);
|
|||||||
#define VISIT_SHAPE(X)
|
#define VISIT_SHAPE(X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define ICMP(W,X) ({ AUTO wt = (W); AUTO xt = (X); (wt>xt?1:0)-(wt<xt?1:0); })
|
#define ICMP(W,X) ({ AUTO wt = (W); AUTO xt = (X); (wt>xt?1:0)-(wt<xt?1:0); })
|
||||||
SHOULD_INLINE i32 compareFloat(f64 w, f64 x) {
|
SHOULD_INLINE i32 floatCompare(f64 w, f64 x) { // w •Cmp x
|
||||||
if (RARE(w!=w || x!=x)) return (w!=w) - (x!=x);
|
if (RARE(w!=w || x!=x)) return (w!=w) - (x!=x);
|
||||||
#if __x86_64__
|
#if __x86_64__
|
||||||
return (w>x) - !(w>=x); // slightly better codegen from being able to reuse the same compare instruction
|
return (w>x) - !(w>=x); // slightly better codegen from being able to reuse the same compare instruction
|
||||||
@ -324,9 +326,13 @@ SHOULD_INLINE i32 compareFloat(f64 w, f64 x) {
|
|||||||
return (w>x) - (w<x);
|
return (w>x) - (w<x);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
SHOULD_INLINE bool floatIndistinguishable(f64 a, f64 b) { // whether the floats are indistinguishable by BQN semantics
|
||||||
|
return a==b || (a!=a && b!=b);
|
||||||
|
}
|
||||||
|
|
||||||
NOINLINE i32 compareF(B w, B x);
|
NOINLINE i32 compareF(B w, B x);
|
||||||
static i32 compare(B w, B x) { // doesn't consume; -1 if w<x, 1 if w>x, 0 if w≡x
|
static i32 compare(B w, B x) { // doesn't consume; -1 if w<x, 1 if w>x, 0 if w≡x
|
||||||
if (isNum(w) & isNum(x)) return compareFloat(o2fG(w), o2fG(x));
|
if (isNum(w) & isNum(x)) return floatCompare(o2fG(w), o2fG(x));
|
||||||
if (isC32(w) & isC32(x)) return ICMP(o2cG(w), o2cG(x));
|
if (isC32(w) & isC32(x)) return ICMP(o2cG(w), o2cG(x));
|
||||||
return compareF(w, x);
|
return compareF(w, x);
|
||||||
}
|
}
|
||||||
@ -342,7 +348,7 @@ static bool compatible(B w, B x) {
|
|||||||
return eequal(w, x);
|
return eequal(w, x);
|
||||||
}
|
}
|
||||||
static bool compatibleFloats(f64 a, f64 b) {
|
static bool compatibleFloats(f64 a, f64 b) {
|
||||||
return a==b || (a!=a && b!=b);
|
return floatIndistinguishable(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
NOINLINE usz depthF(B x);
|
NOINLINE usz depthF(B x);
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
%DEF var V←•internal.Variation ⋄ LV←•internal.ListVariations ⋄ CLR←•internal.ClearRefs
|
%DEF var V←•internal.Variation ⋄ LV←•internal.ListVariations ⋄ CLR←•internal.ClearRefs
|
||||||
%DEF tvar %USE var ⋄ _tvar ← {F _𝕣 x: (CLR@) ⊢ {F 𝕩 V x}¨ LV 𝕩; w F _𝕣 x: (CLR@) ⊢ (LV 𝕨) {(𝕨 V w) F 𝕩 V x}⌜ LV 𝕩}
|
%DEF tvar %USE var ⋄ _tvar ← {F _𝕣 x: (CLR@) ⊢ {F 𝕩 V x}¨ LV 𝕩; w F _𝕣 x: (CLR@) ⊢ (LV 𝕨) {(𝕨 V w) F 𝕩 V x}⌜ LV 𝕩}
|
||||||
|
%DEF eqvar %USE tvar ⋄ _eqvar ← {r ← 𝕨 𝔽 _tvar 𝕩 ⋄ !∘≡⟜(⊑r)¨ r ⋄ ⊑r}
|
||||||
|
|
||||||
# standard system values
|
# standard system values
|
||||||
|
|
||||||
@ -280,6 +281,8 @@ a←3 ⋄ 12 {𝕊: a+↩𝕩}•_timed 10 ⋄ a %% 123
|
|||||||
E←•internal.EEqual ⋄ a←(¯1⊸×≍⊢) (↕3)∾∞∾0÷0 ⋄ {𝕩!(a 𝕏 0)E a 𝕏 •ParseFloat"-0" ⋄ 𝕩!(0 𝕏 a)E(•ParseFloat"-0") 𝕏 a}¨ (⊢∾{𝕏¨}¨) ⟨+,-,×,÷,⋆,√,⌊,⌈,|,¬,∧,∨,<,>,≠,=,≤,≥, •math.Atan2,•math.Comb,•math.Hypot⟩
|
E←•internal.EEqual ⋄ a←(¯1⊸×≍⊢) (↕3)∾∞∾0÷0 ⋄ {𝕩!(a 𝕏 0)E a 𝕏 •ParseFloat"-0" ⋄ 𝕩!(0 𝕏 a)E(•ParseFloat"-0") 𝕏 a}¨ (⊢∾{𝕏¨}¨) ⟨+,-,×,÷,⋆,√,⌊,⌈,|,¬,∧,∨,<,>,≠,=,≤,≥, •math.Atan2,•math.Comb,•math.Hypot⟩
|
||||||
E←•internal.EEqual ⋄ {! (𝕏 4⥊0) E 𝕏 1↓¯1×π∾4⥊0}¨ (⊢∾{𝕏¨}¨) ⟨+,-,×,÷,⋆,√,⌊,⌈,|,¬, •math.Sin,•math.Cos,•math.Tan,•math.Asin,•math.Acos,•math.Atan,•math.Sinh,•math.Cosh,•math.Tanh,•math.Asinh,•math.Acosh,•math.Atanh,•math.Cbrt,•math.Log2,•math.Log10,•math.Log1p,•math.Expm1,•math.Fact,•math.LogFact,•math.Erf,•math.ErfC⟩
|
E←•internal.EEqual ⋄ {! (𝕏 4⥊0) E 𝕏 1↓¯1×π∾4⥊0}¨ (⊢∾{𝕏¨}¨) ⟨+,-,×,÷,⋆,√,⌊,⌈,|,¬, •math.Sin,•math.Cos,•math.Tan,•math.Asin,•math.Acos,•math.Atan,•math.Sinh,•math.Cosh,•math.Tanh,•math.Asinh,•math.Acosh,•math.Atanh,•math.Cbrt,•math.Log2,•math.Log10,•math.Log1p,•math.Expm1,•math.Fact,•math.LogFact,•math.Erf,•math.ErfC⟩
|
||||||
•internal.EEqual´¨ 1⊏˘¨{⟨•math.Atan2⟜2⁼𝕩, •math.Atan2⟜0⁼𝕩, 2⊸•math.Atan2⁼𝕩, 0⊸•math.Atan2⁼𝕩⟩} (¯1⊸×≍⊢) 1.2‿0 %% 1‿1‿1‿1
|
•internal.EEqual´¨ 1⊏˘¨{⟨•math.Atan2⟜2⁼𝕩, •math.Atan2⟜0⁼𝕩, 2⊸•math.Atan2⁼𝕩, 0⊸•math.Atan2⁼𝕩⟩} (¯1⊸×≍⊢) 1.2‿0 %% 1‿1‿1‿1
|
||||||
|
(0÷0) •internal.EEqual -0÷0 %% 1
|
||||||
|
%USE eqvar ⋄ •internal.EEqual _eqvar⟜- ⟨0÷0, 3⥊0⟩ %% 1
|
||||||
|
|
||||||
{15 𝕏 10}¨ ⟨•math.GCD,•math.LCM⟩ %% 5‿30
|
{15 𝕏 10}¨ ⟨•math.GCD,•math.LCM⟩ %% 5‿30
|
||||||
⌊1e5×{0.1 𝕏 0.2}¨ ⟨•math.Atan2,•math.Comb,•math.Hypot,•math.Atan2⁼,•math.Atan2˜⁼⟩ %% 110714‿96959‿22360‿2027‿49331
|
⌊1e5×{0.1 𝕏 0.2}¨ ⟨•math.Atan2,•math.Comb,•math.Hypot,•math.Atan2⁼,•math.Atan2˜⁼⟩ %% 110714‿96959‿22360‿2027‿49331
|
||||||
|
|||||||
@ -213,6 +213,7 @@ n←500 ⋄ a←↕n ⋄ i←(-n)+↕2×n ⋄ r←⌽(2×n)⥊a ⋄ ! (⌽a) ≡
|
|||||||
≍⌾(1‿2⊸⌽) 5‿5⥊↕25 %% 1‿5‿5⥊22‿23‿24‿20‿21‿2‿3‿4‿0‿1‿7‿8‿9‿5‿6‿12‿13‿14‿10‿11‿17‿18‿19‿15‿16
|
≍⌾(1‿2⊸⌽) 5‿5⥊↕25 %% 1‿5‿5⥊22‿23‿24‿20‿21‿2‿3‿4‿0‿1‿7‿8‿9‿5‿6‿12‿13‿14‿10‿11‿17‿18‿19‿15‿16
|
||||||
|
|
||||||
# NaN things
|
# NaN things
|
||||||
|
⟨@⋈0÷0, @⋈-0÷0⟩⌾(0‿0⊸⊏) ⋈3 %% ⋈@ ⋈ 0÷0
|
||||||
(
|
(
|
||||||
%USE eqvar
|
%USE eqvar
|
||||||
_test_ ← { set Repl _𝕣_ different exp:
|
_test_ ← { set Repl _𝕣_ different exp:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user