@@ -69,7 +69,7 @@ test_that("size integer division evaluates numeric operands before casting", {
6969 }
7070
7171 code <- suppressWarnings(r2f(fn ))
72- expect_match(as.character(code ), " floor (" , fixed = TRUE )
72+ expect_match(as.character(code ), " aint (" , fixed = TRUE )
7373 expect_match(as.character(code ), " real(x, kind=c_double)" , fixed = TRUE )
7474 expect_match(as.character(code ), " real(y, kind=c_double)" , fixed = TRUE )
7575 expect_match(code @ c_bridge , " floor(" , fixed = TRUE )
@@ -89,6 +89,46 @@ test_that("size integer division rounds negative quotients down", {
8989 expect_quick_identical(fn , list (- 3L , 2L ))
9090})
9191
92+ test_that(" size floor division remains real before outer arithmetic" , {
93+ fn <- function (x , y , z ) {
94+ declare(
95+ type(x = double(1 )),
96+ type(y = double(1 )),
97+ type(z = double(1 ))
98+ )
99+ out <- double(1 )
100+ local <- double(as.integer((x %/% y ) / z ) + 10L )
101+ out [1 ] <- as.double(length(local ))
102+ out
103+ }
104+
105+ code <- r2f(fn )
106+ expect_match(as.character(code ), " aint(" , fixed = TRUE )
107+ expect_quick_identical(
108+ fn ,
109+ list (1e20 , 3 , 1e19 ),
110+ list (- 1e20 , 3 , 1e19 )
111+ )
112+
113+ returned <- function (x , y , z ) {
114+ declare(
115+ type(x = double(1 )),
116+ type(y = double(1 )),
117+ type(z = double(1 ))
118+ )
119+ out <- double(as.integer((x %/% y ) / z ) + 10L )
120+ for (i in seq_len(length(out ))) {
121+ out [i ] <- as.double(i )
122+ }
123+ out
124+ }
125+ expect_quick_identical(
126+ returned ,
127+ list (1e20 , 3 , 1e19 ),
128+ list (- 1e20 , 3 , 1e19 )
129+ )
130+ })
131+
92132test_that(" size modulo uses the divisor's sign" , {
93133 fn <- function (x , y ) {
94134 declare(type(x = integer(1 )), type(y = integer(1 )))
0 commit comments