Skip to content

Commit d65e9a5

Browse files
author
maechler
committed
subassignment <complex>[i] <- NA should only touch the real part
git-svn-id: https://svn.r-project.org/R/trunk@88444 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent a7cf22d commit d65e9a5

File tree

3 files changed

+41
-14
lines changed

3 files changed

+41
-14
lines changed

doc/NEWS.Rd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@
193193
problem was that the text transformation matrix was not reset
194194
so glyphs would be rendered incorrectly (often completely outside
195195
the device, i.e., not visible).
196+
197+
\item \code{<complex>[i] <- NA} now only sets the \emph{real} part to
198+
\code{NA}, consistently with the \code{as.complex(NA)} behaviour
199+
since \R 4.4.0; thanks to \I{Mikael Jagan}'s \PR{18918}.
200+
196201
}
197202
}
198203
}

src/main/subassign.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ static SEXP VectorAssign(SEXP call, SEXP rho, SEXP x, SEXP s, SEXP y)
753753
int iy = INTEGER_ELT(y, iny);
754754
if (iy == NA_INTEGER) {
755755
px[ii].r = NA_REAL;
756-
px[ii].i = NA_REAL;
756+
px[ii].i = 0.0;
757757
}
758758
else {
759759
px[ii].r = iy;
@@ -771,7 +771,7 @@ static SEXP VectorAssign(SEXP call, SEXP rho, SEXP x, SEXP s, SEXP y)
771771
double ry = REAL_ELT(y, iny);
772772
if (ISNA(ry)) {
773773
px[ii].r = NA_REAL;
774-
px[ii].i = NA_REAL;
774+
px[ii].i = 0.0;
775775
}
776776
else {
777777
px[ii].r = ry;
@@ -1064,7 +1064,7 @@ static SEXP MatrixAssign(SEXP call, SEXP rho, SEXP x, SEXP s, SEXP y)
10641064
int iy = INTEGER_ELT(y, k);
10651065
if (iy == NA_INTEGER) {
10661066
px[ij].r = NA_REAL;
1067-
px[ij].i = NA_REAL;
1067+
px[ij].i = 0.0;
10681068
}
10691069
else {
10701070
px[ij].r = iy;
@@ -1082,7 +1082,7 @@ static SEXP MatrixAssign(SEXP call, SEXP rho, SEXP x, SEXP s, SEXP y)
10821082
double ry = REAL_ELT(y, k);
10831083
if (ISNA(ry)) {
10841084
px[ij].r = NA_REAL;
1085-
px[ij].i = NA_REAL;
1085+
px[ij].i = 0.0;
10861086
}
10871087
else {
10881088
px[ij].r = ry;
@@ -1297,7 +1297,7 @@ static SEXP ArrayAssign(SEXP call, SEXP rho, SEXP x, SEXP s, SEXP y)
12971297
int iy = INTEGER_ELT(y, iny);
12981298
if (iy == NA_INTEGER) {
12991299
px[ii].r = NA_REAL;
1300-
px[ii].i = NA_REAL;
1300+
px[ii].i = 0.0;
13011301
}
13021302
else {
13031303
px[ii].r = iy;
@@ -1315,7 +1315,7 @@ static SEXP ArrayAssign(SEXP call, SEXP rho, SEXP x, SEXP s, SEXP y)
13151315
double ry = REAL_ELT(y, iny);
13161316
if (ISNA(ry)) {
13171317
px[ii].r = NA_REAL;
1318-
px[ii].i = NA_REAL;
1318+
px[ii].i = 0.0;
13191319
}
13201320
else {
13211321
px[ii].r = ry;
@@ -1590,6 +1590,7 @@ NORET static void errorNotSubsettable(SEXP x)
15901590
{
15911591
SEXP call = R_CurrentExpression; /* behave like error() */
15921592
SEXP cond = R_makeNotSubsettableError(x, call);
1593+
PROTECT(cond);
15931594
R_signalErrorCondition(cond, call);
15941595
UNPROTECT(1); /* cond; not reached */
15951596
}
@@ -1598,6 +1599,7 @@ NORET static void errorMissingSubscript(SEXP x)
15981599
{
15991600
SEXP call = R_CurrentExpression; /* behave like error() */
16001601
SEXP cond = R_makeMissingSubscriptError(x, call);
1602+
PROTECT(cond);
16011603
R_signalErrorCondition(cond, call);
16021604
UNPROTECT(1); /* cond; not reached */
16031605
}
@@ -1637,7 +1639,7 @@ attribute_hidden SEXP do_subassign_dflt(SEXP call, SEXP op, SEXP args, SEXP rho)
16371639
oldtype = 0;
16381640
if (TYPEOF(x) == LISTSXP || TYPEOF(x) == LANGSXP) {
16391641
oldtype = TYPEOF(x);
1640-
PROTECT(x = PairToVectorList(x));
1642+
x = PairToVectorList(x);
16411643
}
16421644
else if (xlength(x) == 0) {
16431645
if (xlength(y) == 0 && (isNull(x) || TYPEOF(x) == TYPEOF(y) ||
@@ -1648,13 +1650,10 @@ attribute_hidden SEXP do_subassign_dflt(SEXP call, SEXP op, SEXP args, SEXP rho)
16481650
}
16491651
else {
16501652
/* bug PR#2590 coerce only if null */
1651-
if(isNull(x)) PROTECT(x = coerceVector(x, TYPEOF(y)));
1652-
else PROTECT(x);
1653+
if(isNull(x)) x = coerceVector(x, TYPEOF(y));
16531654
}
16541655
}
1655-
else {
1656-
PROTECT(x);
1657-
}
1656+
PROTECT(x);
16581657

16591658
switch (TYPEOF(x)) {
16601659
case LGLSXP:
@@ -1946,7 +1945,7 @@ do_subassign2_dflt(SEXP call, SEXP op, SEXP args, SEXP rho)
19461945

19471946
if (INTEGER_ELT(y, 0) == NA_INTEGER) {
19481947
COMPLEX(x)[offset].r = NA_REAL;
1949-
COMPLEX(x)[offset].i = NA_REAL;
1948+
COMPLEX(x)[offset].i = 0.0;
19501949
}
19511950
else {
19521951
COMPLEX(x)[offset].r = INTEGER_ELT(y, 0);
@@ -1958,7 +1957,7 @@ do_subassign2_dflt(SEXP call, SEXP op, SEXP args, SEXP rho)
19581957

19591958
if (ISNA(REAL_ELT(y, 0))) {
19601959
COMPLEX(x)[offset].r = NA_REAL;
1961-
COMPLEX(x)[offset].i = NA_REAL;
1960+
COMPLEX(x)[offset].i = 0.0;
19621961
}
19631962
else {
19641963
COMPLEX(x)[offset].r = REAL_ELT(y, 0);

tests/reg-tests-1e.R

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,6 +2053,29 @@ options(op)
20532053
## used to signal 3 warnings
20542054

20552055

2056+
## subassigning from real to complex keeping zero imaginary part
2057+
ll <- list(NA, 0L, NA_integer_, 0, NA_real_, NaN, -Inf, Inf,
2058+
0i, NA_complex_)
2059+
rr <- vapply(ll, Re, 0)
2060+
ii <- vapply(ll, Im, 0) # all 0, but the very last
2061+
chk <- function (x, y = as.vector(x)) stopifnot(identical(Re(y), rr),
2062+
identical(Im(y), ii))
2063+
chk(unlist(ll))
2064+
a1 <- a2 <- complex(m <- length(ll))
2065+
for (i in seq_len(m)) a1[i] <- a2[[i]] <- ll[[i]]
2066+
chk(a1); chk(a2)
2067+
a1 <- a2 <- array(0i, c(m))
2068+
for (i in seq_len(m)) a1[i] <- a2[[i]] <- ll[[i]]
2069+
chk(a1); chk(a2)
2070+
a1 <- a2 <- array(0i, c(m, 1L))
2071+
for (i in seq_len(m)) a1[i, 1L] <- a2[[i, 1L]] <- ll[[i]]
2072+
chk(a1); chk(a2)
2073+
a1 <- a2 <- array(0i, c(m, 1L, 1L))
2074+
for (i in seq_len(m)) a1[i, 1L, 1L] <- a2[[i, 1L, 1L]] <- ll[[i]]
2075+
chk(a1); chk(a2)
2076+
## Im(.)s had more NA's than just at the end, in R <= 4.5.z
2077+
2078+
20562079

20572080
## keep at end
20582081
rbind(last = proc.time() - .pt,

0 commit comments

Comments
 (0)