[Rcpp-commits] r3325 - pkg/int64/inst/include/int64
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sat Nov 12 11:18:41 CET 2011
Author: romain
Date: 2011-11-12 11:18:40 +0100 (Sat, 12 Nov 2011)
New Revision: 3325
Modified:
pkg/int64/inst/include/int64/arith.h
Log:
arithmetic operators with NA handling
Modified: pkg/int64/inst/include/int64/arith.h
===================================================================
--- pkg/int64/inst/include/int64/arith.h 2011-11-12 09:27:48 UTC (rev 3324)
+++ pkg/int64/inst/include/int64/arith.h 2011-11-12 10:18:40 UTC (rev 3325)
@@ -20,17 +20,73 @@
#ifndef int64__arith__h
#define int64__arith__h
-
+
+/* borrowed from R (arithmetic.c) */
+# define OPPOSITE_SIGNS(x, y) ((x < 0) ^ (y < 0))
+# define GOODISUM(x, y, z) (((x) > 0) ? ((y) < (z)) : ! ((y) < (z)))
+# define GOODIDIFF(x, y, z) (!(OPPOSITE_SIGNS(x, y) && OPPOSITE_SIGNS(x, z)))
+# define GOODIPROD(x, y, z) ((long double) (x) * (long double) (y) == (z))
+
+
namespace int64{
namespace internal{
-template <typename T> inline T plus(T x1,T x2){ return x1 + x2 ; }
-template <typename T> inline T minus(T x1,T x2){ return x1 - x2 ; }
-template <typename T> inline T times(T x1,T x2){ return x1 * x2 ; }
-template <typename T> inline T divide(T x1,T x2){ return x1/x2 ; }
-template <typename T> inline T modulo(T x1,T x2){ return x1 % x2 ; }
-template <typename T> inline T int_div(T x1,T x2){ return x1 / x2 ; }
+template <typename T> inline T plus(T x1,T x2){
+ const T na = int64::LongVector<T>::na ;
+ if( x1 == na || x2 == na ){
+ return na ;
+ }
+ T res = x1 + x2 ;
+ if (res != na && GOODISUM(x1, x2, res)){
+ return res ;
+ }
+ return na ;
+}
+template <typename T> inline T minus(T x1,T x2){
+ const T na = int64::LongVector<T>::na ;
+ if( x1 == na || x2 == na){
+ return na ;
+ }
+ T res = x1 - x2 ;
+ if( res != na && GOODIDIFF(x1,x2,res) ){
+ return res ;
+ }
+ return na ;
+}
+template <typename T> inline T times(T x1,T x2){
+ const T na = int64::LongVector<T>::na ;
+ if( x1 == na || x2 == na){
+ return na ;
+ }
+ T res = x1 * x2 ;
+ if( res != na && GOODIPROD(x1,x2,res)){
+ return res ;
+ }
+ return na ;
+}
+template <typename T> inline T divide(T x1,T x2){
+ const T na = int64::LongVector<T>::na ;
+ if( x1 == na || x2 == na ){
+ return na ;
+ }
+ return x1/x2 ;
+}
+template <typename T> inline T modulo(T x1,T x2){
+ const T na = int64::LongVector<T>::na ;
+ if( x1 == na || x2 == na ){
+ return na ;
+ }
+ return x1 % x2 ;
+}
+template <typename T> inline T int_div(T x1,T x2){
+ const T na = int64::LongVector<T>::na ;
+ if( x1 == na || x2 == na ){
+ return na ;
+ }
+ return x1 / x2 ;
+}
+
template <typename LONG, LONG Fun(LONG x1, LONG x2)>
SEXP arith_long_long(SEXP e1, SEXP e2){
int64::LongVector<LONG> x1( e1 ) ;
More information about the Rcpp-commits
mailing list