@@ -131,6 +131,12 @@ jtXfromB(J jt, A w, void *yv) {
131131 !jt->jerr ;
132132}
133133
134+ template <typename T>
135+ static auto
136+ inplace_negate (T& u, int64_t n) {
137+ std::transform (u, u + n, u, [](auto v) { return -v; });
138+ }
139+
134140static B
135141jtXfromI (J jt, A w, void *yv) {
136142 I u[XIDIG];
@@ -146,7 +152,7 @@ jtXfromI(J jt, A w, void *yv) {
146152 }
147153 ++length;
148154 *u += b;
149- if (0 > c) std::transform (u, u + XIDIG, u, []( auto v) { return -v; } );
155+ if (0 > c) inplace_negate (u, XIDIG);
150156 return jtvec (jt, INT, length, u);
151157 });
152158 return !jt->jerr ;
@@ -187,8 +193,9 @@ jtxd1(J jt, D p, I mode) {
187193 if (!m) {
188194 u[0 ] = 0 ;
189195 ++m;
190- } else if (0 > p)
191- DO (m, u[i] = -u[i];);
196+ } else if (0 > p) {
197+ inplace_negate (u, m);
198+ }
192199 A z = jtxstd (jt, jtvec (jt, INT, m, u));
193200 EPILOG (z);
194201}
@@ -210,6 +217,14 @@ jtBfromX(J jt, A w, void *yv) {
210217 return 1 ;
211218}
212219
220+ template <typename T>
221+ [[nodiscard]] static auto
222+ value_from_X (X p) -> T {
223+ auto const n = AN (p);
224+ auto const v = std::reverse_iterator (AV (p) + n);
225+ return std::accumulate (v, v + n, T{}, [](auto d, auto v) { return v + d * XBASE; });
226+ }
227+
213228static B
214229jtIfromX (J jt, A w, void *yv) {
215230 I a, i, m, n, *u, *x;
@@ -222,11 +237,7 @@ jtIfromX(J jt, A w, void *yv) {
222237 for (i = 0 ; i < n; ++i) {
223238 c = v[i];
224239 if (!(1 != jtxcompare (jt, q, c) && 1 != jtxcompare (jt, c, p))) return 0 ;
225- m = AN (c);
226- u = AV (c) + m - 1 ;
227- a = 0 ;
228- DO (m, a = *u-- + a * XBASE;);
229- x[i] = a;
240+ x[i] = value_from_X<int64_t >(c);
230241 }
231242 return 1 ;
232243}
@@ -235,11 +246,10 @@ static B
235246jtDfromX (J jt, A w, void *yv) {
236247 auto const wv = XAV (w);
237248 std::transform (wv, wv + AN (w), static_cast <D *>(yv), [](auto p) {
238- auto const n = AN (p);
239- auto const v = std::reverse_iterator (AV (p) + n);
240- if (*v == XPINF) return inf;
241- if (*v == XNINF) return infm;
242- return std::accumulate (v, v + n, 0.0 , [](auto d, auto v) { return v + d * XBASE; });
249+ auto const c = AV (p)[AN (p)-1 ];
250+ if (c == XPINF) return inf;
251+ if (c == XNINF) return infm;
252+ return value_from_X<double >(p);
243253 });
244254 return 1 ;
245255}
0 commit comments