diff --git a/R/bit64-package.R b/R/bit64-package.R new file mode 100644 index 0000000..724b274 --- /dev/null +++ b/R/bit64-package.R @@ -0,0 +1,898 @@ +#! \name{bit64-package} +#! \alias{bit64-package} +#! \alias{bit64} +#! \alias{integer64} +#! \alias{is.integer64} +#! \alias{is.integer.integer64} +#! \alias{is.vector.integer64} +#! %as.vector.integer64 removed as requested by the CRAN maintainer \alias{as.vector.integer64} +#! \alias{length<-.integer64} +#! \alias{print.integer64} +#! \alias{str.integer64} +#! \docType{package} +#! \title{ +#! A S3 class for vectors of 64bit integers +#! } +#! \description{ +#! Package 'bit64' provides fast serializable S3 atomic 64bit (signed) integers +#! that can be used in vectors, matrices, arrays and data.frames. Methods are +#! available for coercion from and to logicals, integers, doubles, characters +#! and factors as well as many elementwise and summary functions. +#! \cr +#! \bold{Version 0.8} +#! With 'integer64' vectors you can store very large integers at the expense +#! of 64 bits, which is by factor 7 better than 'int64' from package 'int64'. +#! Due to the smaller memory footprint, the atomic vector architecture and +#! using only S3 instead of S4 classes, most operations are one to three orders +#! of magnitude faster: Example speedups are 4x for serialization, 250x for +#! adding, 900x for coercion and 2000x for object creation. Also 'integer64' +#! avoids an ongoing (potentially infinite) penalty for garbage collection +#! observed during existence of 'int64' objects (see code in example section). +#! \cr +#! \bold{Version 0.9} +#! Package 'bit64' - which extends R with fast 64-bit integers - now has fast +#! (single-threaded) implementations the most important univariate algorithmic +#! operations (those based on hashing and sorting). We now have methods for +#! 'match', '%in%', 'duplicated', 'unique', 'table', 'sort', 'order', 'rank', +#! 'quantile', 'median' and 'summary'. Regarding data management we also have +#! novel generics 'unipos' (positions of the unique values), 'tiepos' ( +#! positions of ties), 'keypos' (positions of foreign keys in a sorted +#! dimension table) and derived methods 'as.factor' and 'as.ordered'. This 64- +#! bit functionality is implemented carefully to be not slower than the +#! respective 32-bit operations in Base R and also to avoid outlying waiting +#! times observed with 'order', 'rank' and 'table' (speedup factors 20/16/200 +#! respective). This increases the dataset size with wich we can work truly +#! interactive. The speed is achieved by simple heuristic optimizers in high- +#! level functions choosing the best from multiple low-level algorithms and +#! further taking advantage of a novel caching if activated. In an example R +#! session using a couple of these operations the 64-bit integers performed 22x +#! faster than base 32-bit integers, hash-caching improved this to 24x, +#! sortorder-caching was most efficient with 38x (caching hashing and sorting +#! is not worth it with 32x at duplicated RAM consumption). +#! } +#! \usage{ +#! integer64(length) +#! +#! \method{is}{integer64}(x) +#! +#! \method{length}{integer64}(x) <- value +#! +#! \method{print}{integer64}(x, quote=FALSE, ...) +#! +#! \method{str}{integer64}(object, vec.len = strO$vec.len, give.head = TRUE, give.length = give.head, ...) +#! } +#! \arguments{ +#! \item{length}{ length of vector using \code{\link{integer}} } +#! \item{x}{ an integer64 vector } +#! \item{object}{ an integer64 vector } +#! \item{value}{ an integer64 vector of values to be assigned } +#! \item{quote}{ logical, indicating whether or not strings should be printed with surrounding quotes. } +#! \item{vec.len}{ see \code{\link[utils]{str}} } +#! \item{give.head}{ see \code{\link[utils]{str}} } +#! \item{give.length}{ see \code{\link[utils]{str}} } +#! \item{...}{ further arguments to the \code{\link{NextMethod}} } +#! } +#! \details{ +#! \tabular{ll}{ +#! Package: \tab bit64\cr +#! Type: \tab Package\cr +#! Version: \tab 0.5.0\cr +#! Date: \tab 2011-12-12\cr +#! License: \tab GPL-2\cr +#! LazyLoad: \tab yes\cr +#! Encoding: \tab latin1\cr +#! } +#! } +#! \section{Design considerations}{ +#! 64 bit integers are related to big data: we need them to overcome address space limitations. +#! Therefore performance of the 64 bit integer type is critical. +#! In the S language -- designed in 1975 -- atomic objects were defined to be vectors for a couple of good reasons: +#! simplicity, option for implicit parallelization, good cache locality. +#! In recent years many analytical databases have learnt that lesson: column based data bases provide superior performance +#! for many applications, the result are products such as MonetDB, Sybase IQ, Vertica, Exasol, Ingres Vectorwise. +#! If we introduce 64 bit integers not natively in Base R but as an external package, we should at least strive to +#! make them as 'basic' as possible. Therefore the design choice of bit64 not only differs from \code{int64}, it is obvious: +#! Like the other atomic types in Base R, we model data type 'integer64' as a contiguous \code{\link{atomic}} vector in memory, +#! and we use the more basic \code{\link{S3}} class system, not \code{\link{S4}}. Like package \code{int64} we want our 'integer64' to be \code{\link{serialize}able}, +#! therefore we also use an existing data type as the basis. Again the choice is obvious: R has only one 64 bit data type: doubles. +#! By using \code{\link{double}s}, \code{integer64} \code{\link{inherits}} some functionality such as \code{\link{is.atomic}}, \code{\link{length}}, +#! \code{\link{length<-}}, \code{\link{names}}, \code{\link{names<-}}, \code{\link{dim}}, \code{\link{dim<-}}, \code{\link{dimnames}}, \code{\link{dimnames}}. +#! \cr +#! Our R level functions strictly follow the functional programming paragdim: +#! no modification of arguments or other side-effects. Before version 0.93 we internally deviated from the strict paradigm +#! in order to boost performance. Our C functions do not create new return values, +#! instead we pass-in the memory to be returned as an argument. This gives us the freedom to apply the C-function +#! to new or old vectors, which helps to avoid unnecessary memory allocation, unnecessary copying and unnecessary garbage collection. +#! Prior to 0.93 \emph{within} our R functions we also deviated from conventional R programming by not using \code{\link{attr<-}} and \code{\link{attributes<-}} +#! because they always did new memory allocation and copying in older R versions. If we wanted to set attributes of return values that we have freshly created, +#! we instead used functions \code{\link[bit:getsetattr]{setattr}} and \code{\link[bit:getsetattr]{setattributes}} from package \code{\link[bit]{bit}}. +#! From version 0.93 \code{\link[bit:getsetattr]{setattr}} is only used for manipulating \code{\link{cache}} objects, in \code{\link{ramsort.integer64}} and \code{\link{sort.integer64}} and in \code{\link{as.data.frame.integer64}}. +#! } +#! \section{Arithmetic precision and coercion}{ +#! The fact that we introduce 64 bit long long integers -- without introducing 128-bit long doubles -- creates some subtle challenges: +#! Unlike 32 bit \code{\link{integer}s}, the \code{integer64} are no longer a proper subset of \code{\link{double}}. +#! If a binary arithmetic operation does involve a \code{double} and a \code{integer}, it is a no-brainer to return \code{double} +#! without loss of information. If an \code{integer64} meets a \code{double}, it is not trivial what type to return. +#! Switching to \code{integer64} limits our ability to represent very large numbers, switching to \code{double} limits our ability +#! to distinguish \code{x} from \code{x+1}. Since the latter is the purpose of introducing 64 bit integers, we usually return \code{integer64} +#! from functions involving \code{integer64}, for example in \code{\link[=c.integer64]{c}}, \code{\link[=cbind.integer64]{cbind}} +#! and \code{\link[=rbind.integer64]{rbind}}. +#! \cr +#! Different from Base R, our operators \code{\link[=+.integer64]{+}}, +#! \code{\link[=-.integer64]{-}}, \code{\link[=\%/\%.integer64]{\%/\%}} and \code{\link[=\%\%.integer64]{\%\%}} coerce their arguments to +#! \code{integer64} and always return \code{integer64}. +#! \cr +#! The multiplication operator \code{\link[=*.integer64]{*}} coerces its first argument to \code{integer64} +#! but allows its second argument to be also \code{double}: the second argument is internaly coerced to 'long double' +#! and the result of the multiplication is returned as \code{integer64}. +#! \cr +#! The division \code{\link[=/.integer64]{/}} and power \code{\link[=^.integer64]{^}} operators also coerce their first argument to \code{integer64} +#! and coerce internally their second argument to 'long double', they return as \code{double}, like \code{\link[=sqrt.integer64]{sqrt}}, +#! \code{\link[=log.integer64]{log}}, \code{\link[=log2.integer64]{log2}} and \code{\link[=log10.integer64]{log10}} do. +#! +#! \tabular{ccccccccc}{ +#! \bold{argument1} \tab \bold{op} \tab \bold{argument2} \tab \bold{->} \tab \bold{coerced1} \tab \bold{op} \tab \bold{coerced2} \tab \bold{->} \tab \bold{result} \cr +#! integer64 \tab + \tab double \tab -> \tab integer64 \tab + \tab integer64 \tab -> \tab integer64 \cr +#! double \tab + \tab integer64 \tab -> \tab integer64 \tab + \tab integer64 \tab -> \tab integer64 \cr +#! integer64 \tab - \tab double \tab -> \tab integer64 \tab - \tab integer64 \tab -> \tab integer64 \cr +#! double \tab - \tab integer64 \tab -> \tab integer64 \tab - \tab integer64 \tab -> \tab integer64 \cr +#! integer64 \tab \%/\% \tab double \tab -> \tab integer64 \tab \%/\% \tab integer64 \tab -> \tab integer64 \cr +#! double \tab \%/\% \tab integer64 \tab -> \tab integer64 \tab \%/\% \tab integer64 \tab -> \tab integer64 \cr +#! integer64 \tab \%\% \tab double \tab -> \tab integer64 \tab \%\% \tab integer64 \tab -> \tab integer64 \cr +#! double \tab \%\% \tab integer64 \tab -> \tab integer64 \tab \%\% \tab integer64 \tab -> \tab integer64 \cr +#! integer64 \tab * \tab double \tab -> \tab integer64 \tab * \tab long double \tab -> \tab integer64 \cr +#! double \tab * \tab integer64 \tab -> \tab integer64 \tab * \tab integer64 \tab -> \tab integer64 \cr +#! integer64 \tab / \tab double \tab -> \tab integer64 \tab / \tab long double \tab -> \tab double \cr +#! double \tab / \tab integer64 \tab -> \tab integer64 \tab / \tab long double \tab -> \tab double \cr +#! integer64 \tab ^ \tab double \tab -> \tab integer64 \tab / \tab long double \tab -> \tab double \cr +#! double \tab ^ \tab integer64 \tab -> \tab integer64 \tab / \tab long double \tab -> \tab double \cr +#! } +#! } +#! \section{Creating and testing S3 class 'integer64'}{ +#! Our creator function \code{integer64} takes an argument \code{length}, creates an atomic double vector of this length, +#! attaches an S3 class attribute 'integer64' to it, and that's it. We simply rely on S3 method dispatch and interpret those +#! 64bit elements as 'long long int'. +#! \cr +#! \code{\link{is.double}} currently returns TRUE for \code{integer64} and might return FALSE in a later release. +#! Consider \code{is.double} to have undefined behavior and do query \code{is.integer64} \emph{before} querying \code{is.double}. +#! %As a second line of defense against misinterpretation we make \code{\link{is.double}} +#! %return \code{FALSE} by making it S3 generic and adding a method \code{\link{as.double.integer64}}. +#! The methods \code{\link{is.integer64}} and \code{\link{is.vector}} both return \code{TRUE} for \code{integer64}. +#! Note that we did not patch \code{\link{storage.mode}} and \code{\link{typeof}}, which both continue returning 'double' +#! Like for 32 bit \code{\link{integer}}, \code{\link{mode}} returns 'numeric' and \code{\link{as.double}}) tries coercing to \code{\link{double}}). +#! It is possible that 'integer64' becomes a \code{vmode} in package \code{ff}. +#! \cr +#! Further methods for creating \code{integer64} are \code{\link[=range.integer64]{range}} which returns the range of the data type if calles without arguments, +#! \code{\link[=rep.integer64]{rep}}, \code{\link[=seq.integer64]{seq}}. +#! \cr +#! For all available methods on \code{integer64} vectors see the index below and the examples. +#! } +#! \section{Index of implemented methods}{ +#! \tabular{rrl}{ +#! \bold{creating,testing,printing} \tab \bold{see also} \tab \bold{description} \cr +#! \code{NA_integer64_} \tab \code{\link{NA_integer_}} \tab NA constant \cr +#! \code{integer64} \tab \code{\link{integer}} \tab create zero atomic vector \cr +#! \code{\link{runif64}} \tab \code{\link{runif}} \tab create random vector \cr +#! \code{\link{rep.integer64}} \tab \code{\link{rep}} \tab \cr +#! \code{\link{seq.integer64}} \tab \code{\link{seq}} \tab \cr +#! \code{\link{is.integer64}} \tab \code{\link{is}} \tab \cr +#! \tab \code{\link{is.integer}} \tab inherited from Base R \cr +#! %\code{\link{is.double.integer64}} \tab \code{\link{is.double}} \tab \cr +#! \code{\link{is.vector.integer64}} \tab \code{\link{is.vector}} \tab \cr +#! \code{\link{identical.integer64}} \tab \code{\link{identical}} \tab \cr +#! \code{\link{length<-.integer64}} \tab \code{\link{length<-}} \tab \cr +#! \tab \code{\link{length}} \tab inherited from Base R \cr +#! \tab \code{\link{names<-}} \tab inherited from Base R \cr +#! \tab \code{\link{names}} \tab inherited from Base R \cr +#! \tab \code{\link{dim<-}} \tab inherited from Base R \cr +#! \tab \code{\link{dim}} \tab inherited from Base R \cr +#! \tab \code{\link{dimnames<-}} \tab inherited from Base R \cr +#! \tab \code{\link{dimnames}} \tab inherited from Base R \cr +#! \tab \code{\link{str}} \tab inherited from Base R, does not print values correctly \cr +#! \code{\link{print.integer64}} \tab \code{\link{print}} \tab \cr +#! \code{\link{str.integer64}} \tab \code{\link{str}} \tab \cr +#! \cr +#! \bold{coercing to integer64} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{as.integer64}} \tab \tab generic \cr +#! \code{\link{as.integer64.bitstring}} \tab \code{\link{as.bitstring}} \tab \cr +#! \code{\link{as.integer64.character}} \tab \code{\link{character}} \tab \cr +#! \code{\link{as.integer64.double}} \tab \code{\link{double}} \tab \cr +#! \code{\link{as.integer64.integer}} \tab \code{\link{integer}} \tab \cr +#! \code{\link{as.integer64.integer64}} \tab \code{integer64} \tab \cr +#! \code{\link{as.integer64.logical}} \tab \code{\link{logical}} \tab \cr +#! \code{\link{as.integer64.NULL}} \tab \code{\link{NULL}} \tab \cr +#! \cr +#! \bold{coercing from integer64} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{as.list.integer64}} \tab \code{\link{as.list}} \tab generic \cr +#! \code{\link{as.bitstring}} \tab \code{\link{as.bitstring}} \tab generic \cr +#! \code{\link{as.bitstring.integer64}} \tab \tab \cr +#! \code{\link{as.character.integer64}} \tab \code{\link{as.character}} \tab \cr +#! \code{\link{as.double.integer64}} \tab \code{\link{as.double}} \tab \cr +#! \code{\link{as.integer.integer64}} \tab \code{\link{as.integer}} \tab \cr +#! \code{\link{as.logical.integer64}} \tab \code{\link{as.logical}} \tab \cr +#! %as.vector.integer64 removed as requested by the CRAN maintainer \code{\link{as.vector.integer64}} \tab \code{\link{as.vector}} \tab \cr +#! \cr +#! \bold{data structures} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{c.integer64}} \tab \code{\link{c}} \tab vector concatenate \cr +#! \code{\link{cbind.integer64}} \tab \code{\link{cbind}} \tab column bind \cr +#! \code{\link{rbind.integer64}} \tab \code{\link{rbind}} \tab row bind \cr +#! \code{\link{as.data.frame.integer64}} \tab \code{\link{as.data.frame}} \tab coerce atomic object to data.frame \cr +#! \tab \code{\link{data.frame}} \tab inherited from Base R since we have coercion \cr +#! \cr +#! \bold{subscripting} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{[.integer64}} \tab \code{\link{[}} \tab vector and array extract \cr +#! \code{\link{[<-.integer64}} \tab \code{\link{[<-}} \tab vector and array assign \cr +#! \code{\link{[[.integer64}} \tab \code{\link{[[}} \tab scalar extract \cr +#! \code{\link{[[<-.integer64}} \tab \code{\link{[[<-}} \tab scalar assign \cr +#! \cr +#! \bold{binary operators} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{+.integer64}} \tab \code{\link{+}} \tab returns integer64 \cr +#! \code{\link{-.integer64}} \tab \code{\link{-}} \tab returns integer64 \cr +#! \code{\link{*.integer64}} \tab \code{\link{*}} \tab returns integer64 \cr +#! \code{\link{^.integer64}} \tab \code{\link{^}} \tab returns double \cr +#! \code{\link{/.integer64}} \tab \code{\link{/}} \tab returns double \cr +#! \code{\link{\%/\%.integer64}} \tab \code{\link{\%/\%}} \tab returns integer64 \cr +#! \code{\link{\%\%.integer64}} \tab \code{\link{\%\%}} \tab returns integer64 \cr +#! \cr +#! \bold{comparison operators} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{==.integer64}} \tab \code{\link{==}} \tab \cr +#! \code{\link{!=.integer64}} \tab \code{\link{!=}} \tab \cr +#! \code{\link{<.integer64}} \tab \code{\link{<}} \tab \cr +#! \code{\link{<=.integer64}} \tab \code{\link{<=}} \tab \cr +#! \code{\link{>.integer64}} \tab \code{\link{>}} \tab \cr +#! \code{\link{>=.integer64}} \tab \code{\link{>=}} \tab \cr +#! \cr +#! \bold{logical operators} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{!.integer64}} \tab \code{\link{!}} \tab \cr +#! \code{\link{&.integer64}} \tab \code{\link{&}} \tab \cr +#! \code{\link{|.integer64}} \tab \code{\link{|}} \tab \cr +#! \code{\link{xor.integer64}} \tab \code{\link{xor}} \tab \cr +#! \cr +#! \bold{math functions} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{is.na.integer64}} \tab \code{\link{is.na}} \tab returns logical \cr +#! \code{\link{format.integer64}} \tab \code{\link{format}} \tab returns character \cr +#! \code{\link{abs.integer64}} \tab \code{\link{abs}} \tab returns integer64 \cr +#! \code{\link{sign.integer64}} \tab \code{\link{sign}} \tab returns integer64 \cr +#! \code{\link{log.integer64}} \tab \code{\link{log}} \tab returns double \cr +#! \code{\link{log10.integer64}} \tab \code{\link{log10}} \tab returns double \cr +#! \code{\link{log2.integer64}} \tab \code{\link{log2}} \tab returns double \cr +#! \code{\link{sqrt.integer64}} \tab \code{\link{sqrt}} \tab returns double \cr +#! \code{\link{ceiling.integer64}} \tab \code{\link{ceiling}} \tab dummy returning its argument \cr +#! \code{\link{floor.integer64}} \tab \code{\link{floor}} \tab dummy returning its argument \cr +#! \code{\link{trunc.integer64}} \tab \code{\link{trunc}} \tab dummy returning its argument \cr +#! \code{\link{round.integer64}} \tab \code{\link{round}} \tab dummy returning its argument \cr +#! \code{\link{signif.integer64}} \tab \code{\link{signif}} \tab dummy returning its argument \cr +#! \cr +#! \bold{cumulative functions} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{cummin.integer64}} \tab \code{\link{cummin}} \tab \cr +#! \code{\link{cummax.integer64}} \tab \code{\link{cummax}} \tab \cr +#! \code{\link{cumsum.integer64}} \tab \code{\link{cumsum}} \tab \cr +#! \code{\link{cumprod.integer64}} \tab \code{\link{cumprod}} \tab \cr +#! \code{\link{diff.integer64}} \tab \code{\link{diff}} \tab \cr +#! \cr +#! \bold{summary functions} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{range.integer64}} \tab \code{\link{range}} \tab \cr +#! \code{\link{min.integer64}} \tab \code{\link{min}} \tab \cr +#! \code{\link{max.integer64}} \tab \code{\link{max}} \tab \cr +#! \code{\link{sum.integer64}} \tab \code{\link{sum}} \tab \cr +#! \code{\link{mean.integer64}} \tab \code{\link{mean}} \tab \cr +#! \code{\link{prod.integer64}} \tab \code{\link{prod}} \tab \cr +#! \code{\link{all.integer64}} \tab \code{\link{all}} \tab \cr +#! \code{\link{any.integer64}} \tab \code{\link{any}} \tab \cr +#! \cr +#! \bold{algorithmically complex functions} \tab \bold{see also} \tab \bold{description (caching)} \cr +#! \code{\link{match.integer64}} \tab \code{\link{match}} \tab position of x in table (h//o/so) \cr +#! \code{\link{\%in\%.integer64}} \tab \code{\link{\%in\%}} \tab is x in table? (h//o/so) \cr +#! \code{\link{duplicated.integer64}} \tab \code{\link{duplicated}} \tab is current element duplicate of previous one? (h//o/so) \cr +#! \code{\link{unique.integer64}} \tab \code{\link{unique}} \tab (shorter) vector of unique values only (h/s/o/so) \cr +#! \code{\link{unipos.integer64}} \tab \code{\link{unipos}} \tab positions corresponding to unique values (h/s/o/so) \cr +#! \code{\link{tiepos.integer64}} \tab \code{\link{tiepos}} \tab positions of values that are tied (//o/so) \cr +#! \code{\link{keypos.integer64}} \tab \code{\link{keypos}} \tab position of current value in sorted list of unique values (//o/so) \cr +#! \code{\link{table.integer64}} \tab \code{\link{table}} \tab unique values and their frequencies (h/s/o/so) \cr +#! \code{\link{sort.integer64}} \tab \code{\link{sort}} \tab sorted vector (/s/o/so) \cr +#! \code{\link{order.integer64}} \tab \code{\link{order}} \tab positions of elements that would create sorted vector (//o/so) \cr +#! \code{\link{rank.integer64}} \tab \code{\link{rank}} \tab (average) ranks of non-NAs, NAs kept in place (/s/o/so) \cr +#! \code{\link{quantile.integer64}} \tab \code{\link{quantile}} \tab (existing) values at specified percentiles (/s/o/so) \cr +#! \code{\link{median.integer64}} \tab \code{\link{median}} \tab (existing) value at percentile 0.5 (/s/o/so) \cr +#! \code{\link{summary.integer64}} \tab \code{\link{summary}} \tab (/s/o/so) \cr +#! \code{\link{all.equal.integer64}} \tab \code{\link{all.equal}} \tab test if two objects are (nearly) equal (/s/o/so) \cr +#! \cr +#! \bold{helper functions} \tab \bold{see also} \tab \bold{description} \cr +#! \code{\link{minusclass}} \tab \code{\link{minusclass}} \tab removing class attritbute \cr +#! \code{\link{plusclass}} \tab \code{\link{plusclass}} \tab inserting class attribute \cr +#! \code{\link{binattr}} \tab \code{\link{binattr}} \tab define binary op behaviour \cr +#! \cr +#! \bold{tested I/O functions} \tab \bold{see also} \tab \bold{description} \cr +#! \tab \code{\link{read.table}} \tab inherited from Base R \cr +#! \tab \code{\link{write.table}} \tab inherited from Base R \cr +#! \tab \code{\link{serialize}} \tab inherited from Base R \cr +#! \tab \code{\link{unserialize}} \tab inherited from Base R \cr +#! \tab \code{\link{save}} \tab inherited from Base R \cr +#! \tab \code{\link{load}} \tab inherited from Base R \cr +#! \tab \code{\link{dput}} \tab inherited from Base R \cr +#! \tab \code{\link{dget}} \tab inherited from Base R \cr +#! } +#! } +#! \section{Limitations inherited from implementing 64 bit integers via an external package}{ +#! \itemize{ +#! \item \bold{vector size} of atomic vectors is still limited to \code{\link{.Machine}$integer.max}. +#! However, external memory extending packages such as \code{ff} or \code{bigmemory} +#! can extend their address space now with \code{integer64}. Having 64 bit integers also help +#! with those not so obvious address issues that arise once we exchange data with SQL databases +#! and datawarehouses, which use big integers as surrogate keys, e.g. on indexed primary key columns. +#! This puts R into a relatively strong position compared to certain commercial statistical +#! softwares, which sell database connectivity but neither have the range of 64 bit integers, +#! nor have integers at all, nor have a single numeric data type in their macro-glue-language. +#! +#! \item \bold{literals} such as \code{123LL} would require changes to Base R, up to then we need to write (and call) +#! \code{as.integer64(123L)} or \code{as.integer64(123)} or \code{as.integer64('123')}. +#! Only the latter allows to specify numbers beyond Base R's numeric data types and therefore is the recommended +#! way to use -- using only one way may facilitate migrating code to literals at a later stage. +#! +#! } +#! } +#! \section{Limitations inherited from Base R, Core team, can you change this?}{ +#! \itemize{ +#! \item \bold{\code{\link{identical}}} with default parameters does not distinguish all bit-patterns of doubles. +#! For testing purposes we provide a wrapper \code{\link{identical.integer64}} that will distinguish all bit-patterns. +#! It would be desireable to have a single call of \code{\link{identical}} handle both, \code{\link{double}} and \code{integer64}. +#! +#! \item the \bold{colon} operator \code{\link{:}} officially does not dispatches S3 methods, however, we have made it generic +#! \preformatted{ +#! from <- lim.integer64()[1] +#! to <- from+99 +#! from:to +#! } +#! As a limitation remains: it will only dispatch at its first argument \code{from} but not at its second \code{to}. +#! +#! \item \bold{\code{\link{is.double}}} does not dispatches S3 methods, However, we have made it generic +#! and it will return \code{FALSE} on \code{integer64}. +#! +#! \item \bold{\code{\link{c}}} only dispatches \code{\link{c.integer64}} if the first argument is \code{integer64} +#! and it does not recursively dispatch the proper method when called with argument \code{recursive=TRUE} +#! Therefore \preformatted{ +#! c(list(integer64,integer64)) +#! } +#! does not work and for now you can only call \preformatted{ +#! c.integer64(list(x,x)) +#! } +#! +#! \item \bold{generic binary operators} fail to dispatch *any* user-defined S3 method +#! if the two arguments have two different S3 classes. For example we have two classes +#! \code{\link[bit]{bit}} and \code{\link[bit]{bitwhich}} sparsely representing boolean vectors +#! and we have methods \code{\link[bit:xor.default]{&.bit}} and \code{\link[bit:xor.default]{&.bitwhich}}. For an expression +#! involving both as in \code{ bit & bitwhich}, none of the two methods is dispatched. +#! Instead a standard method is dispatched, which neither handles \code{\link[bit]{bit}} +#! nor \code{\link[bit]{bitwhich}}. Although it lacks symmetry, the better choice would be to +#! dispatch simply the method of the class of the first argument in case of class conflict. +#! This choice would allow authors of extension packages providing coherent behaviour +#! at least within their contributed classes. But as long as none of the package authors +#! methods is dispatched, he cannot handle the conflicting classes at all. +#! +#! \item \bold{\code{\link{unlist}}} is not generic and if it were, we would face similar problems as with \code{c()} +#! +#! \item \bold{\code{\link{vector}}} with argument \code{mode='integer64'} cannot work without adjustment of Base R +#! \item \bold{\code{\link{as.vector}}} with argument \code{mode='integer64'} cannot work without adjustment of Base R +#! +#! \item \bold{\code{\link{is.vector}}} does not dispatch its method \code{\link{is.vector.integer64}} +#! +#! \item \bold{\code{\link{mode<-}}} drops the class 'integer64' which is returned from \code{as.integer64}. +#! Also it does not remove an existing class 'integer64' when assigning mode 'integer'. +#! +#! \item \bold{\code{\link{storage.mode<-}}} does not support external data types such as \code{as.integer64} +#! +#! \item \bold{\code{\link{matrix}}} does drop the 'integer64' class attribute. +#! +#! \item \bold{\code{\link{array}}} does drop the 'integer64' class attribute. +#! In current R versions (1.15.1) this can be circumvented by activating the function +#! \code{as.vector.integer64} further down this file. +#! However, the CRAN maintainer has requested to remove \code{as.vector.integer64}, +#! even at the price of breaking previously working functionality of the package. +#! +#! \item \bold{\code{\link{str}}} does not print the values of \code{integer64} correctly +#! +#! } +#! } +#! \section{further limitations}{ +#! \itemize{ +#! \item \bold{subscripting} non-existing elements and subscripting with \code{NA}s is currently not supported. +#! Such subscripting currently returns \code{9218868437227407266} instead of \code{NA} (the \code{NA} value of the underlying double code). +#! Following the full R behaviour here would either destroy performance or require extensive C-coding. +#! } +#! } +#! \note{ +#! \code{integer64} are useful for handling database keys and exact counting in +-2^63. +#! Do not use them as replacement for 32bit integers, integer64 are not +#! supported for subscripting by R-core and they have different semantics +#! when combined with double. Do understand that \code{integer64} can only be +#! useful over \code{double} if we do not coerce it to \code{double}. \cr +#! \cr +#! While \cr +#! integer + double -> double + double -> double \cr +#! or \cr +#! 1L + 0.5 -> 1.5 \cr +#! for additive operations we coerce to \code{integer64} \cr +#! integer64 + double -> integer64 + integer64 -> integer64 \cr +#! hence \cr +#! as.integer64(1) + 0.5 -> 1LL + 0LL -> 1LL \cr +#! \cr +#! see section "Arithmetic precision and coercion" above +#! } +#! \value{ +#! \code{integer64} returns a vector of 'integer64', +#! i.e. a vector of \code{\link{double}} decorated with class 'integer64'. +#! } +#! \author{ +#! Jens Oehlschlägel +#! Maintainer: Jens Oehlschlägel +#! } +#! \keyword{ package } +#! \keyword{ classes } +#! \keyword{ manip } +#! \seealso{ \code{\link{integer}} in base R } +#! \examples{ +#! message("Using integer64 in vector") +#! x <- integer64(8) # create 64 bit vector +#! x +#! is.atomic(x) # TRUE +#! is.integer64(x) # TRUE +#! is.numeric(x) # TRUE +#! is.integer(x) # FALSE - debatable +#! is.double(x) # FALSE - might change +#! x[] <- 1:2 # assigned value is recycled as usual +#! x[1:6] # subscripting as usual +#! length(x) <- 13 # changing length as usual +#! x +#! rep(x, 2) # replicate as usual +#! seq(as.integer64(1), 10) # seq.integer64 is dispatched on first given argument +#! seq(to=as.integer64(10), 1) # seq.integer64 is dispatched on first given argument +#! seq.integer64(along.with=x) # or call seq.integer64 directly +#! # c.integer64 is dispatched only if *first* argument is integer64 ... +#! x <- c(x,runif(length(x), max=100)) +#! # ... and coerces everything to integer64 - including double +#! x +#! names(x) <- letters # use names as usual +#! x +#! +#! message("Using integer64 in array - note that 'matrix' currently does not work") +#! message("as.vector.integer64 removed as requested by the CRAN maintainer") +#! message("as consequence 'array' also does not work anymore") +#! %y <- array(as.integer64(NA), dim=c(3,4), dimnames=list(letters[1:3], LETTERS[1:4])) +#! message("we still can create a matrix or array by assigning 'dim'") +#! y <- rep(as.integer64(NA), 12) +#! dim(y) <- c(3,4) +#! dimnames(y) <- list(letters[1:3], LETTERS[1:4]) +#! y["a",] <- 1:2 # assigning as usual +#! y +#! y[1:2,-4] # subscripting as usual +#! # cbind.integer64 dispatched on any argument and coerces everything to integer64 +#! cbind(E=1:3, F=runif(3, 0, 100), G=c("-1","0","1"), y) +#! +#! message("Using integer64 in data.frame") +#! str(as.data.frame(x)) +#! str(as.data.frame(y)) +#! str(data.frame(y)) +#! str(data.frame(I(y))) +#! d <- data.frame(x=x, y=runif(length(x), 0, 100)) +#! d +#! d$x +#! +#! message("Using integer64 with csv files") +#! fi64 <- tempfile() +#! write.csv(d, file=fi64, row.names=FALSE) +#! e <- read.csv(fi64, colClasses=c("integer64", NA)) +#! unlink(fi64) +#! str(e) +#! identical.integer64(d$x,e$x) +#! +#! message("Serializing and unserializing integer64") +#! dput(d, fi64) +#! e <- dget(fi64) +#! identical.integer64(d$x,e$x) +#! e <- d[,] +#! save(e, file=fi64) +#! rm(e) +#! load(file=fi64) +#! identical.integer64(d,e) +#! +#! ### A couple of unit tests follow hidden in a dontshow{} directive ### +#! \dontshow{ +#! message("Testing identical.integer64") +#! i64 <- as.double(NA); class(i64) <- "integer64" +#! stopifnot(identical(unclass(i64-1), unclass(i64+1))) +#! stopifnot(identical(i64-1, i64+1)) +#! stopifnot(!identical.integer64(i64-1, i64+1)) +#! +#! message("Testing dispatch of 'c' method") +#! stopifnot(identical.integer64(c(integer64(0), NA), as.integer64(NA))) +#! message("Dispatch on the second argument fails and we want to be notified once that changes") +#! stopifnot(!identical.integer64(c(NA, integer64(0)), as.integer64(NA))) +#! +#! message("Testing minus and plus") +#! d64 <- c(-.Machine$double.base^.Machine$double.digits, -.Machine$integer.max, -1, 0, 1, .Machine$integer.max, .Machine$double.base^.Machine$double.digits) +#! i64 <- as.integer64(d64) +#! stopifnot(identical.integer64(i64-1+1,i64)) +#! stopifnot(identical.integer64(i64+1-1,i64)) +#! +#! message("Testing minus and plus edge cases and 'rev'\nUBSAN signed integer overflow expected for type 'long long int'\nThis is a false UBSAN alarm because overflow is detected and NA returned") +#! stopifnot(identical.integer64(lim.integer64()+1-1, c(lim.integer64()[1], NA))) +#! stopifnot(identical.integer64(rev(lim.integer64())-1+1, c(lim.integer64()[2], NA))) +#! +#! message("Testing 'range.integer64', multiplication and integer division") +#! i64 <- integer64(63) +#! i64[1] <- 1 +#! for (i in 2:63) +#! i64[i] <- 2*i64[i-1] +#! stopifnot(identical.integer64(i64 * rev(i64), rep(i64[63], 63))) +#! for (i in 63:2) +#! i64[i-1] <- i64[i]\%/\%2 +#! stopifnot(identical.integer64(i64 * rev(i64), rep(i64[63], 63))) +#! for (i in 63:2) +#! i64[i-1] <- i64[i]/2 +#! stopifnot(identical.integer64(i64 * rev(i64), rep(i64[63], 63))) +#! stopifnot(identical.integer64(c( -i64[63] - (i64[63]-1), i64[63]+(i64[63]-1) ), lim.integer64())) +#! +#! stopifnot(identical.integer64(i64[-1]\%/\%2*as.integer64(2), i64[-1])) +#! stopifnot(identical.integer64(i64[-1]\%/\%2L*as.integer64(2), i64[-1])) +#! stopifnot(identical.integer64(i64[-1]/2*as.integer64(2), i64[-1])) +#! stopifnot(identical.integer64(i64[-1]/2*as.integer64(2), i64[-1])) +#! +#! stopifnot(identical.integer64(i64[-63]*2\%/\%2, i64[-63])) +#! stopifnot(identical.integer64(i64[-63]*2L\%/\%2L, i64[-63])) +#! stopifnot(identical.integer64(as.integer64(i64[-63]*2/2), i64[-63])) +#! stopifnot(identical.integer64(as.integer64(i64[-63]*2L/2L), i64[-63])) +#! +#! message("Testing sqrt, power and log") +#! stopifnot(identical.integer64( as.integer64(sqrt(i64[-1][c(FALSE, TRUE)])*sqrt(i64[-1][c(FALSE, TRUE)])), i64[-1][c(FALSE, TRUE)] )) +#! +#! stopifnot(identical.integer64(as.integer64(2)^(0:62), i64)) +#! stopifnot(identical.integer64(as.integer64(0:62), as.integer64(round(log2(i64))))) +#! stopifnot(identical.integer64(as.integer64(round(log(as.integer64(2)^(0:62), 2))), as.integer64(0:62))) +#! stopifnot(identical.integer64(as.integer64(round(log(as.integer64(3)^(0:39), 3))), as.integer64(0:39))) +#! stopifnot(identical.integer64(as.integer64(round(log(as.integer64(10)^(0:18), 10))), as.integer64(0:18))) +#! stopifnot(identical.integer64(as.integer64(round(log10(as.integer64(10)^(0:18)))), as.integer64(0:18))) +#! +#! stopifnot(identical.integer64((as.integer64(2)^(1:62))^(1/1:62), as.integer64(rep(2, 62)))) +#! stopifnot(identical.integer64((as.integer64(3)^(1:39))^(1/1:39), as.integer64(rep(3, 39)))) +#! stopifnot(identical.integer64((as.integer64(10)^(1:18))^(1/1:18), as.integer64(rep(10, 18)))) +#! +#! message("Testing c and rep") +#! stopifnot(identical.integer64( as.integer64(rep(1:3, 1:3)), rep(as.integer64(1:3), 1:3))) +#! stopifnot(identical.integer64( as.integer64(rep(1:3, 3)), rep(as.integer64(1:3), 3))) +#! +#! x <- as.double(c(NA,NA,NA)) +#! class(x) <- "integer64" +#! x <- x + -1:1 +#! stopifnot(identical.integer64(rep(x, 3), c(x,x,x) )) +#! stopifnot(identical.integer64(c.integer64(list(x,x,x), recursive=TRUE), c(x,x,x) )) +#! +#! message("Testing seq") +#! stopifnot(identical.integer64(seq(as.integer64(1), 10, 2), as.integer64(seq(1, 10, 2)) )) +#! stopifnot(identical.integer64(seq(as.integer64(1), by=2, length.out=5), as.integer64(seq(1, by=2, length.out=5)) )) +#! stopifnot(identical.integer64(seq(as.integer64(1), by=2, length.out=6), as.integer64(seq(1, by=2, length.out=6)) )) +#! stopifnot(identical.integer64(seq.integer64(along.with=3:5), as.integer64(seq(along.with=3:5)) )) +#! stopifnot(identical.integer64(seq(as.integer64(1), to=-9), as.integer64(seq(1, to=-9)) )) +#! +#! message("Testing cbind and rbind") +#! stopifnot(identical.integer64( cbind(as.integer64(1:3), 1:3), {x <- rep(as.integer64(1:3), 2); dim(x)<-c(3,2);x})) +#! stopifnot(identical.integer64( rbind(as.integer64(1:3), 1:3), t({x <- rep(as.integer64(1:3), 2); dim(x)<-c(3,2);x}))) +#! +#! message("Testing coercion") +#! stopifnot(identical( as.double(as.integer64(c(NA, seq(0, 9, 0.25)))), as.double(as.integer(c(NA, seq(0, 9, 0.25)))))) +#! stopifnot(identical( as.character(as.integer64(c(NA, seq(0, 9, 0.25)))), as.character(as.integer(c(NA, seq(0, 9, 0.25)))))) +#! stopifnot(identical( as.integer(as.integer64(c(NA, seq(0, 9, 0.25)))), as.integer(c(NA, seq(0, 9, 0.25))))) +#! stopifnot(identical( as.logical(as.integer64(c(NA, seq(0, 9, 0.25)))), as.logical(as.integer(c(NA, seq(0, 9, 0.25)))))) +#! stopifnot(identical( as.integer(as.integer64(c(NA, FALSE, TRUE))), as.integer(c(NA, FALSE, TRUE)))) +#! stopifnot(identical( as.integer64(as.integer(as.integer64(-9:9))), as.integer64(-9:9))) +#! stopifnot(identical( as.integer64(as.double(as.integer64(-9:9))), as.integer64(-9:9))) +#! stopifnot(identical( as.integer64(as.character(as.integer64(-9:9))), as.integer64(-9:9))) +#! stopifnot(identical( as.integer64(as.character(lim.integer64())), lim.integer64())) +#! +#! message("-- testing logical operators --") +#! stopifnot(identical.integer64(!c(NA, -1:1), !c(as.integer64(NA), -1:1))) +#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)&rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))&as.integer64(rep(c(NA, -1:1), rep(4, 4))))) +#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)|rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))|as.integer64(rep(c(NA, -1:1), rep(4, 4))))) +#! stopifnot(identical.integer64(xor(rep(c(NA, -1:1), 4),rep(c(NA, -1:1), rep(4, 4))), xor(as.integer64(rep(c(NA, -1:1), 4)),as.integer64(rep(c(NA, -1:1), rep(4, 4)))))) +#! +#! message("-- testing comparison operators --") +#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)==rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))==as.integer64(rep(c(NA, -1:1), rep(4, 4))))) +#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)!=rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))!=as.integer64(rep(c(NA, -1:1), rep(4, 4))))) +#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)>rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))>as.integer64(rep(c(NA, -1:1), rep(4, 4))))) +#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)>=rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))>=as.integer64(rep(c(NA, -1:1), rep(4, 4))))) +#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)} \tab \bold{coerced1} \tab \bold{op} \tab \bold{coerced2} \tab \bold{->} \tab \bold{result} \cr -#! integer64 \tab + \tab double \tab -> \tab integer64 \tab + \tab integer64 \tab -> \tab integer64 \cr -#! double \tab + \tab integer64 \tab -> \tab integer64 \tab + \tab integer64 \tab -> \tab integer64 \cr -#! integer64 \tab - \tab double \tab -> \tab integer64 \tab - \tab integer64 \tab -> \tab integer64 \cr -#! double \tab - \tab integer64 \tab -> \tab integer64 \tab - \tab integer64 \tab -> \tab integer64 \cr -#! integer64 \tab \%/\% \tab double \tab -> \tab integer64 \tab \%/\% \tab integer64 \tab -> \tab integer64 \cr -#! double \tab \%/\% \tab integer64 \tab -> \tab integer64 \tab \%/\% \tab integer64 \tab -> \tab integer64 \cr -#! integer64 \tab \%\% \tab double \tab -> \tab integer64 \tab \%\% \tab integer64 \tab -> \tab integer64 \cr -#! double \tab \%\% \tab integer64 \tab -> \tab integer64 \tab \%\% \tab integer64 \tab -> \tab integer64 \cr -#! integer64 \tab * \tab double \tab -> \tab integer64 \tab * \tab long double \tab -> \tab integer64 \cr -#! double \tab * \tab integer64 \tab -> \tab integer64 \tab * \tab integer64 \tab -> \tab integer64 \cr -#! integer64 \tab / \tab double \tab -> \tab integer64 \tab / \tab long double \tab -> \tab double \cr -#! double \tab / \tab integer64 \tab -> \tab integer64 \tab / \tab long double \tab -> \tab double \cr -#! integer64 \tab ^ \tab double \tab -> \tab integer64 \tab / \tab long double \tab -> \tab double \cr -#! double \tab ^ \tab integer64 \tab -> \tab integer64 \tab / \tab long double \tab -> \tab double \cr -#! } -#! } -#! \section{Creating and testing S3 class 'integer64'}{ -#! Our creator function \code{integer64} takes an argument \code{length}, creates an atomic double vector of this length, -#! attaches an S3 class attribute 'integer64' to it, and that's it. We simply rely on S3 method dispatch and interpret those -#! 64bit elements as 'long long int'. -#! \cr -#! \code{\link{is.double}} currently returns TRUE for \code{integer64} and might return FALSE in a later release. -#! Consider \code{is.double} to have undefined behavior and do query \code{is.integer64} \emph{before} querying \code{is.double}. -#! %As a second line of defense against misinterpretation we make \code{\link{is.double}} -#! %return \code{FALSE} by making it S3 generic and adding a method \code{\link{as.double.integer64}}. -#! The methods \code{\link{is.integer64}} and \code{\link{is.vector}} both return \code{TRUE} for \code{integer64}. -#! Note that we did not patch \code{\link{storage.mode}} and \code{\link{typeof}}, which both continue returning 'double' -#! Like for 32 bit \code{\link{integer}}, \code{\link{mode}} returns 'numeric' and \code{\link{as.double}}) tries coercing to \code{\link{double}}). -#! It is possible that 'integer64' becomes a \code{vmode} in package \code{ff}. -#! \cr -#! Further methods for creating \code{integer64} are \code{\link[=range.integer64]{range}} which returns the range of the data type if calles without arguments, -#! \code{\link[=rep.integer64]{rep}}, \code{\link[=seq.integer64]{seq}}. -#! \cr -#! For all available methods on \code{integer64} vectors see the index below and the examples. -#! } -#! \section{Index of implemented methods}{ -#! \tabular{rrl}{ -#! \bold{creating,testing,printing} \tab \bold{see also} \tab \bold{description} \cr -#! \code{NA_integer64_} \tab \code{\link{NA_integer_}} \tab NA constant \cr -#! \code{integer64} \tab \code{\link{integer}} \tab create zero atomic vector \cr -#! \code{\link{runif64}} \tab \code{\link{runif}} \tab create random vector \cr -#! \code{\link{rep.integer64}} \tab \code{\link{rep}} \tab \cr -#! \code{\link{seq.integer64}} \tab \code{\link{seq}} \tab \cr -#! \code{\link{is.integer64}} \tab \code{\link{is}} \tab \cr -#! \tab \code{\link{is.integer}} \tab inherited from Base R \cr -#! %\code{\link{is.double.integer64}} \tab \code{\link{is.double}} \tab \cr -#! \code{\link{is.vector.integer64}} \tab \code{\link{is.vector}} \tab \cr -#! \code{\link{identical.integer64}} \tab \code{\link{identical}} \tab \cr -#! \code{\link{length<-.integer64}} \tab \code{\link{length<-}} \tab \cr -#! \tab \code{\link{length}} \tab inherited from Base R \cr -#! \tab \code{\link{names<-}} \tab inherited from Base R \cr -#! \tab \code{\link{names}} \tab inherited from Base R \cr -#! \tab \code{\link{dim<-}} \tab inherited from Base R \cr -#! \tab \code{\link{dim}} \tab inherited from Base R \cr -#! \tab \code{\link{dimnames<-}} \tab inherited from Base R \cr -#! \tab \code{\link{dimnames}} \tab inherited from Base R \cr -#! \tab \code{\link{str}} \tab inherited from Base R, does not print values correctly \cr -#! \code{\link{print.integer64}} \tab \code{\link{print}} \tab \cr -#! \code{\link{str.integer64}} \tab \code{\link{str}} \tab \cr -#! \cr -#! \bold{coercing to integer64} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{as.integer64}} \tab \tab generic \cr -#! \code{\link{as.integer64.bitstring}} \tab \code{\link{as.bitstring}} \tab \cr -#! \code{\link{as.integer64.character}} \tab \code{\link{character}} \tab \cr -#! \code{\link{as.integer64.double}} \tab \code{\link{double}} \tab \cr -#! \code{\link{as.integer64.integer}} \tab \code{\link{integer}} \tab \cr -#! \code{\link{as.integer64.integer64}} \tab \code{integer64} \tab \cr -#! \code{\link{as.integer64.logical}} \tab \code{\link{logical}} \tab \cr -#! \code{\link{as.integer64.NULL}} \tab \code{\link{NULL}} \tab \cr -#! \cr -#! \bold{coercing from integer64} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{as.list.integer64}} \tab \code{\link{as.list}} \tab generic \cr -#! \code{\link{as.bitstring}} \tab \code{\link{as.bitstring}} \tab generic \cr -#! \code{\link{as.bitstring.integer64}} \tab \tab \cr -#! \code{\link{as.character.integer64}} \tab \code{\link{as.character}} \tab \cr -#! \code{\link{as.double.integer64}} \tab \code{\link{as.double}} \tab \cr -#! \code{\link{as.integer.integer64}} \tab \code{\link{as.integer}} \tab \cr -#! \code{\link{as.logical.integer64}} \tab \code{\link{as.logical}} \tab \cr -#! %as.vector.integer64 removed as requested by the CRAN maintainer \code{\link{as.vector.integer64}} \tab \code{\link{as.vector}} \tab \cr -#! \cr -#! \bold{data structures} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{c.integer64}} \tab \code{\link{c}} \tab vector concatenate \cr -#! \code{\link{cbind.integer64}} \tab \code{\link{cbind}} \tab column bind \cr -#! \code{\link{rbind.integer64}} \tab \code{\link{rbind}} \tab row bind \cr -#! \code{\link{as.data.frame.integer64}} \tab \code{\link{as.data.frame}} \tab coerce atomic object to data.frame \cr -#! \tab \code{\link{data.frame}} \tab inherited from Base R since we have coercion \cr -#! \cr -#! \bold{subscripting} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{[.integer64}} \tab \code{\link{[}} \tab vector and array extract \cr -#! \code{\link{[<-.integer64}} \tab \code{\link{[<-}} \tab vector and array assign \cr -#! \code{\link{[[.integer64}} \tab \code{\link{[[}} \tab scalar extract \cr -#! \code{\link{[[<-.integer64}} \tab \code{\link{[[<-}} \tab scalar assign \cr -#! \cr -#! \bold{binary operators} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{+.integer64}} \tab \code{\link{+}} \tab returns integer64 \cr -#! \code{\link{-.integer64}} \tab \code{\link{-}} \tab returns integer64 \cr -#! \code{\link{*.integer64}} \tab \code{\link{*}} \tab returns integer64 \cr -#! \code{\link{^.integer64}} \tab \code{\link{^}} \tab returns double \cr -#! \code{\link{/.integer64}} \tab \code{\link{/}} \tab returns double \cr -#! \code{\link{\%/\%.integer64}} \tab \code{\link{\%/\%}} \tab returns integer64 \cr -#! \code{\link{\%\%.integer64}} \tab \code{\link{\%\%}} \tab returns integer64 \cr -#! \cr -#! \bold{comparison operators} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{==.integer64}} \tab \code{\link{==}} \tab \cr -#! \code{\link{!=.integer64}} \tab \code{\link{!=}} \tab \cr -#! \code{\link{<.integer64}} \tab \code{\link{<}} \tab \cr -#! \code{\link{<=.integer64}} \tab \code{\link{<=}} \tab \cr -#! \code{\link{>.integer64}} \tab \code{\link{>}} \tab \cr -#! \code{\link{>=.integer64}} \tab \code{\link{>=}} \tab \cr -#! \cr -#! \bold{logical operators} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{!.integer64}} \tab \code{\link{!}} \tab \cr -#! \code{\link{&.integer64}} \tab \code{\link{&}} \tab \cr -#! \code{\link{|.integer64}} \tab \code{\link{|}} \tab \cr -#! \code{\link{xor.integer64}} \tab \code{\link{xor}} \tab \cr -#! \cr -#! \bold{math functions} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{is.na.integer64}} \tab \code{\link{is.na}} \tab returns logical \cr -#! \code{\link{format.integer64}} \tab \code{\link{format}} \tab returns character \cr -#! \code{\link{abs.integer64}} \tab \code{\link{abs}} \tab returns integer64 \cr -#! \code{\link{sign.integer64}} \tab \code{\link{sign}} \tab returns integer64 \cr -#! \code{\link{log.integer64}} \tab \code{\link{log}} \tab returns double \cr -#! \code{\link{log10.integer64}} \tab \code{\link{log10}} \tab returns double \cr -#! \code{\link{log2.integer64}} \tab \code{\link{log2}} \tab returns double \cr -#! \code{\link{sqrt.integer64}} \tab \code{\link{sqrt}} \tab returns double \cr -#! \code{\link{ceiling.integer64}} \tab \code{\link{ceiling}} \tab dummy returning its argument \cr -#! \code{\link{floor.integer64}} \tab \code{\link{floor}} \tab dummy returning its argument \cr -#! \code{\link{trunc.integer64}} \tab \code{\link{trunc}} \tab dummy returning its argument \cr -#! \code{\link{round.integer64}} \tab \code{\link{round}} \tab dummy returning its argument \cr -#! \code{\link{signif.integer64}} \tab \code{\link{signif}} \tab dummy returning its argument \cr -#! \cr -#! \bold{cumulative functions} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{cummin.integer64}} \tab \code{\link{cummin}} \tab \cr -#! \code{\link{cummax.integer64}} \tab \code{\link{cummax}} \tab \cr -#! \code{\link{cumsum.integer64}} \tab \code{\link{cumsum}} \tab \cr -#! \code{\link{cumprod.integer64}} \tab \code{\link{cumprod}} \tab \cr -#! \code{\link{diff.integer64}} \tab \code{\link{diff}} \tab \cr -#! \cr -#! \bold{summary functions} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{range.integer64}} \tab \code{\link{range}} \tab \cr -#! \code{\link{min.integer64}} \tab \code{\link{min}} \tab \cr -#! \code{\link{max.integer64}} \tab \code{\link{max}} \tab \cr -#! \code{\link{sum.integer64}} \tab \code{\link{sum}} \tab \cr -#! \code{\link{mean.integer64}} \tab \code{\link{mean}} \tab \cr -#! \code{\link{prod.integer64}} \tab \code{\link{prod}} \tab \cr -#! \code{\link{all.integer64}} \tab \code{\link{all}} \tab \cr -#! \code{\link{any.integer64}} \tab \code{\link{any}} \tab \cr -#! \cr -#! \bold{algorithmically complex functions} \tab \bold{see also} \tab \bold{description (caching)} \cr -#! \code{\link{match.integer64}} \tab \code{\link{match}} \tab position of x in table (h//o/so) \cr -#! \code{\link{\%in\%.integer64}} \tab \code{\link{\%in\%}} \tab is x in table? (h//o/so) \cr -#! \code{\link{duplicated.integer64}} \tab \code{\link{duplicated}} \tab is current element duplicate of previous one? (h//o/so) \cr -#! \code{\link{unique.integer64}} \tab \code{\link{unique}} \tab (shorter) vector of unique values only (h/s/o/so) \cr -#! \code{\link{unipos.integer64}} \tab \code{\link{unipos}} \tab positions corresponding to unique values (h/s/o/so) \cr -#! \code{\link{tiepos.integer64}} \tab \code{\link{tiepos}} \tab positions of values that are tied (//o/so) \cr -#! \code{\link{keypos.integer64}} \tab \code{\link{keypos}} \tab position of current value in sorted list of unique values (//o/so) \cr -#! \code{\link{table.integer64}} \tab \code{\link{table}} \tab unique values and their frequencies (h/s/o/so) \cr -#! \code{\link{sort.integer64}} \tab \code{\link{sort}} \tab sorted vector (/s/o/so) \cr -#! \code{\link{order.integer64}} \tab \code{\link{order}} \tab positions of elements that would create sorted vector (//o/so) \cr -#! \code{\link{rank.integer64}} \tab \code{\link{rank}} \tab (average) ranks of non-NAs, NAs kept in place (/s/o/so) \cr -#! \code{\link{quantile.integer64}} \tab \code{\link{quantile}} \tab (existing) values at specified percentiles (/s/o/so) \cr -#! \code{\link{median.integer64}} \tab \code{\link{median}} \tab (existing) value at percentile 0.5 (/s/o/so) \cr -#! \code{\link{summary.integer64}} \tab \code{\link{summary}} \tab (/s/o/so) \cr -#! \code{\link{all.equal.integer64}} \tab \code{\link{all.equal}} \tab test if two objects are (nearly) equal (/s/o/so) \cr -#! \cr -#! \bold{helper functions} \tab \bold{see also} \tab \bold{description} \cr -#! \code{\link{minusclass}} \tab \code{\link{minusclass}} \tab removing class attritbute \cr -#! \code{\link{plusclass}} \tab \code{\link{plusclass}} \tab inserting class attribute \cr -#! \code{\link{binattr}} \tab \code{\link{binattr}} \tab define binary op behaviour \cr -#! \cr -#! \bold{tested I/O functions} \tab \bold{see also} \tab \bold{description} \cr -#! \tab \code{\link{read.table}} \tab inherited from Base R \cr -#! \tab \code{\link{write.table}} \tab inherited from Base R \cr -#! \tab \code{\link{serialize}} \tab inherited from Base R \cr -#! \tab \code{\link{unserialize}} \tab inherited from Base R \cr -#! \tab \code{\link{save}} \tab inherited from Base R \cr -#! \tab \code{\link{load}} \tab inherited from Base R \cr -#! \tab \code{\link{dput}} \tab inherited from Base R \cr -#! \tab \code{\link{dget}} \tab inherited from Base R \cr -#! } -#! } -#! \section{Limitations inherited from implementing 64 bit integers via an external package}{ -#! \itemize{ -#! \item \bold{vector size} of atomic vectors is still limited to \code{\link{.Machine}$integer.max}. -#! However, external memory extending packages such as \code{ff} or \code{bigmemory} -#! can extend their address space now with \code{integer64}. Having 64 bit integers also help -#! with those not so obvious address issues that arise once we exchange data with SQL databases -#! and datawarehouses, which use big integers as surrogate keys, e.g. on indexed primary key columns. -#! This puts R into a relatively strong position compared to certain commercial statistical -#! softwares, which sell database connectivity but neither have the range of 64 bit integers, -#! nor have integers at all, nor have a single numeric data type in their macro-glue-language. -#! -#! \item \bold{literals} such as \code{123LL} would require changes to Base R, up to then we need to write (and call) -#! \code{as.integer64(123L)} or \code{as.integer64(123)} or \code{as.integer64('123')}. -#! Only the latter allows to specify numbers beyond Base R's numeric data types and therefore is the recommended -#! way to use -- using only one way may facilitate migrating code to literals at a later stage. -#! -#! } -#! } -#! \section{Limitations inherited from Base R, Core team, can you change this?}{ -#! \itemize{ -#! \item \bold{\code{\link{identical}}} with default parameters does not distinguish all bit-patterns of doubles. -#! For testing purposes we provide a wrapper \code{\link{identical.integer64}} that will distinguish all bit-patterns. -#! It would be desireable to have a single call of \code{\link{identical}} handle both, \code{\link{double}} and \code{integer64}. -#! -#! \item the \bold{colon} operator \code{\link{:}} officially does not dispatches S3 methods, however, we have made it generic -#! \preformatted{ -#! from <- lim.integer64()[1] -#! to <- from+99 -#! from:to -#! } -#! As a limitation remains: it will only dispatch at its first argument \code{from} but not at its second \code{to}. -#! -#! \item \bold{\code{\link{is.double}}} does not dispatches S3 methods, However, we have made it generic -#! and it will return \code{FALSE} on \code{integer64}. -#! -#! \item \bold{\code{\link{c}}} only dispatches \code{\link{c.integer64}} if the first argument is \code{integer64} -#! and it does not recursively dispatch the proper method when called with argument \code{recursive=TRUE} -#! Therefore \preformatted{ -#! c(list(integer64,integer64)) -#! } -#! does not work and for now you can only call \preformatted{ -#! c.integer64(list(x,x)) -#! } -#! -#! \item \bold{generic binary operators} fail to dispatch *any* user-defined S3 method -#! if the two arguments have two different S3 classes. For example we have two classes -#! \code{\link[bit]{bit}} and \code{\link[bit]{bitwhich}} sparsely representing boolean vectors -#! and we have methods \code{\link[bit:xor.default]{&.bit}} and \code{\link[bit:xor.default]{&.bitwhich}}. For an expression -#! involving both as in \code{ bit & bitwhich}, none of the two methods is dispatched. -#! Instead a standard method is dispatched, which neither handles \code{\link[bit]{bit}} -#! nor \code{\link[bit]{bitwhich}}. Although it lacks symmetry, the better choice would be to -#! dispatch simply the method of the class of the first argument in case of class conflict. -#! This choice would allow authors of extension packages providing coherent behaviour -#! at least within their contributed classes. But as long as none of the package authors -#! methods is dispatched, he cannot handle the conflicting classes at all. -#! -#! \item \bold{\code{\link{unlist}}} is not generic and if it were, we would face similar problems as with \code{c()} -#! -#! \item \bold{\code{\link{vector}}} with argument \code{mode='integer64'} cannot work without adjustment of Base R -#! \item \bold{\code{\link{as.vector}}} with argument \code{mode='integer64'} cannot work without adjustment of Base R -#! -#! \item \bold{\code{\link{is.vector}}} does not dispatch its method \code{\link{is.vector.integer64}} -#! -#! \item \bold{\code{\link{mode<-}}} drops the class 'integer64' which is returned from \code{as.integer64}. -#! Also it does not remove an existing class 'integer64' when assigning mode 'integer'. -#! -#! \item \bold{\code{\link{storage.mode<-}}} does not support external data types such as \code{as.integer64} -#! -#! \item \bold{\code{\link{matrix}}} does drop the 'integer64' class attribute. -#! -#! \item \bold{\code{\link{array}}} does drop the 'integer64' class attribute. -#! In current R versions (1.15.1) this can be circumvented by activating the function -#! \code{as.vector.integer64} further down this file. -#! However, the CRAN maintainer has requested to remove \code{as.vector.integer64}, -#! even at the price of breaking previously working functionality of the package. -#! -#! \item \bold{\code{\link{str}}} does not print the values of \code{integer64} correctly -#! -#! } -#! } -#! \section{further limitations}{ -#! \itemize{ -#! \item \bold{subscripting} non-existing elements and subscripting with \code{NA}s is currently not supported. -#! Such subscripting currently returns \code{9218868437227407266} instead of \code{NA} (the \code{NA} value of the underlying double code). -#! Following the full R behaviour here would either destroy performance or require extensive C-coding. -#! } -#! } -#! \note{ -#! \code{integer64} are useful for handling database keys and exact counting in +-2^63. -#! Do not use them as replacement for 32bit integers, integer64 are not -#! supported for subscripting by R-core and they have different semantics -#! when combined with double. Do understand that \code{integer64} can only be -#! useful over \code{double} if we do not coerce it to \code{double}. \cr -#! \cr -#! While \cr -#! integer + double -> double + double -> double \cr -#! or \cr -#! 1L + 0.5 -> 1.5 \cr -#! for additive operations we coerce to \code{integer64} \cr -#! integer64 + double -> integer64 + integer64 -> integer64 \cr -#! hence \cr -#! as.integer64(1) + 0.5 -> 1LL + 0LL -> 1LL \cr -#! \cr -#! see section "Arithmetic precision and coercion" above -#! } -#! \value{ -#! \code{integer64} returns a vector of 'integer64', -#! i.e. a vector of \code{\link{double}} decorated with class 'integer64'. -#! } -#! \author{ -#! Jens Oehlschlägel -#! Maintainer: Jens Oehlschlägel -#! } -#! \keyword{ package } -#! \keyword{ classes } -#! \keyword{ manip } -#! \seealso{ \code{\link{integer}} in base R } -#! \examples{ -#! message("Using integer64 in vector") -#! x <- integer64(8) # create 64 bit vector -#! x -#! is.atomic(x) # TRUE -#! is.integer64(x) # TRUE -#! is.numeric(x) # TRUE -#! is.integer(x) # FALSE - debatable -#! is.double(x) # FALSE - might change -#! x[] <- 1:2 # assigned value is recycled as usual -#! x[1:6] # subscripting as usual -#! length(x) <- 13 # changing length as usual -#! x -#! rep(x, 2) # replicate as usual -#! seq(as.integer64(1), 10) # seq.integer64 is dispatched on first given argument -#! seq(to=as.integer64(10), 1) # seq.integer64 is dispatched on first given argument -#! seq.integer64(along.with=x) # or call seq.integer64 directly -#! # c.integer64 is dispatched only if *first* argument is integer64 ... -#! x <- c(x,runif(length(x), max=100)) -#! # ... and coerces everything to integer64 - including double -#! x -#! names(x) <- letters # use names as usual -#! x -#! -#! message("Using integer64 in array - note that 'matrix' currently does not work") -#! message("as.vector.integer64 removed as requested by the CRAN maintainer") -#! message("as consequence 'array' also does not work anymore") -#! %y <- array(as.integer64(NA), dim=c(3,4), dimnames=list(letters[1:3], LETTERS[1:4])) -#! message("we still can create a matrix or array by assigning 'dim'") -#! y <- rep(as.integer64(NA), 12) -#! dim(y) <- c(3,4) -#! dimnames(y) <- list(letters[1:3], LETTERS[1:4]) -#! y["a",] <- 1:2 # assigning as usual -#! y -#! y[1:2,-4] # subscripting as usual -#! # cbind.integer64 dispatched on any argument and coerces everything to integer64 -#! cbind(E=1:3, F=runif(3, 0, 100), G=c("-1","0","1"), y) -#! -#! message("Using integer64 in data.frame") -#! str(as.data.frame(x)) -#! str(as.data.frame(y)) -#! str(data.frame(y)) -#! str(data.frame(I(y))) -#! d <- data.frame(x=x, y=runif(length(x), 0, 100)) -#! d -#! d$x -#! -#! message("Using integer64 with csv files") -#! fi64 <- tempfile() -#! write.csv(d, file=fi64, row.names=FALSE) -#! e <- read.csv(fi64, colClasses=c("integer64", NA)) -#! unlink(fi64) -#! str(e) -#! identical.integer64(d$x,e$x) -#! -#! message("Serializing and unserializing integer64") -#! dput(d, fi64) -#! e <- dget(fi64) -#! identical.integer64(d$x,e$x) -#! e <- d[,] -#! save(e, file=fi64) -#! rm(e) -#! load(file=fi64) -#! identical.integer64(d,e) -#! -#! ### A couple of unit tests follow hidden in a dontshow{} directive ### -#! \dontshow{ -#! message("Testing identical.integer64") -#! i64 <- as.double(NA); class(i64) <- "integer64" -#! stopifnot(identical(unclass(i64-1), unclass(i64+1))) -#! stopifnot(identical(i64-1, i64+1)) -#! stopifnot(!identical.integer64(i64-1, i64+1)) -#! -#! message("Testing dispatch of 'c' method") -#! stopifnot(identical.integer64(c(integer64(0), NA), as.integer64(NA))) -#! message("Dispatch on the second argument fails and we want to be notified once that changes") -#! stopifnot(!identical.integer64(c(NA, integer64(0)), as.integer64(NA))) -#! -#! message("Testing minus and plus") -#! d64 <- c(-.Machine$double.base^.Machine$double.digits, -.Machine$integer.max, -1, 0, 1, .Machine$integer.max, .Machine$double.base^.Machine$double.digits) -#! i64 <- as.integer64(d64) -#! stopifnot(identical.integer64(i64-1+1,i64)) -#! stopifnot(identical.integer64(i64+1-1,i64)) -#! -#! message("Testing minus and plus edge cases and 'rev'\nUBSAN signed integer overflow expected for type 'long long int'\nThis is a false UBSAN alarm because overflow is detected and NA returned") -#! stopifnot(identical.integer64(lim.integer64()+1-1, c(lim.integer64()[1], NA))) -#! stopifnot(identical.integer64(rev(lim.integer64())-1+1, c(lim.integer64()[2], NA))) -#! -#! message("Testing 'range.integer64', multiplication and integer division") -#! i64 <- integer64(63) -#! i64[1] <- 1 -#! for (i in 2:63) -#! i64[i] <- 2*i64[i-1] -#! stopifnot(identical.integer64(i64 * rev(i64), rep(i64[63], 63))) -#! for (i in 63:2) -#! i64[i-1] <- i64[i]\%/\%2 -#! stopifnot(identical.integer64(i64 * rev(i64), rep(i64[63], 63))) -#! for (i in 63:2) -#! i64[i-1] <- i64[i]/2 -#! stopifnot(identical.integer64(i64 * rev(i64), rep(i64[63], 63))) -#! stopifnot(identical.integer64(c( -i64[63] - (i64[63]-1), i64[63]+(i64[63]-1) ), lim.integer64())) -#! -#! stopifnot(identical.integer64(i64[-1]\%/\%2*as.integer64(2), i64[-1])) -#! stopifnot(identical.integer64(i64[-1]\%/\%2L*as.integer64(2), i64[-1])) -#! stopifnot(identical.integer64(i64[-1]/2*as.integer64(2), i64[-1])) -#! stopifnot(identical.integer64(i64[-1]/2*as.integer64(2), i64[-1])) -#! -#! stopifnot(identical.integer64(i64[-63]*2\%/\%2, i64[-63])) -#! stopifnot(identical.integer64(i64[-63]*2L\%/\%2L, i64[-63])) -#! stopifnot(identical.integer64(as.integer64(i64[-63]*2/2), i64[-63])) -#! stopifnot(identical.integer64(as.integer64(i64[-63]*2L/2L), i64[-63])) -#! -#! message("Testing sqrt, power and log") -#! stopifnot(identical.integer64( as.integer64(sqrt(i64[-1][c(FALSE, TRUE)])*sqrt(i64[-1][c(FALSE, TRUE)])), i64[-1][c(FALSE, TRUE)] )) -#! -#! stopifnot(identical.integer64(as.integer64(2)^(0:62), i64)) -#! stopifnot(identical.integer64(as.integer64(0:62), as.integer64(round(log2(i64))))) -#! stopifnot(identical.integer64(as.integer64(round(log(as.integer64(2)^(0:62), 2))), as.integer64(0:62))) -#! stopifnot(identical.integer64(as.integer64(round(log(as.integer64(3)^(0:39), 3))), as.integer64(0:39))) -#! stopifnot(identical.integer64(as.integer64(round(log(as.integer64(10)^(0:18), 10))), as.integer64(0:18))) -#! stopifnot(identical.integer64(as.integer64(round(log10(as.integer64(10)^(0:18)))), as.integer64(0:18))) -#! -#! stopifnot(identical.integer64((as.integer64(2)^(1:62))^(1/1:62), as.integer64(rep(2, 62)))) -#! stopifnot(identical.integer64((as.integer64(3)^(1:39))^(1/1:39), as.integer64(rep(3, 39)))) -#! stopifnot(identical.integer64((as.integer64(10)^(1:18))^(1/1:18), as.integer64(rep(10, 18)))) -#! -#! message("Testing c and rep") -#! stopifnot(identical.integer64( as.integer64(rep(1:3, 1:3)), rep(as.integer64(1:3), 1:3))) -#! stopifnot(identical.integer64( as.integer64(rep(1:3, 3)), rep(as.integer64(1:3), 3))) -#! -#! x <- as.double(c(NA,NA,NA)) -#! class(x) <- "integer64" -#! x <- x + -1:1 -#! stopifnot(identical.integer64(rep(x, 3), c(x,x,x) )) -#! stopifnot(identical.integer64(c.integer64(list(x,x,x), recursive=TRUE), c(x,x,x) )) -#! -#! message("Testing seq") -#! stopifnot(identical.integer64(seq(as.integer64(1), 10, 2), as.integer64(seq(1, 10, 2)) )) -#! stopifnot(identical.integer64(seq(as.integer64(1), by=2, length.out=5), as.integer64(seq(1, by=2, length.out=5)) )) -#! stopifnot(identical.integer64(seq(as.integer64(1), by=2, length.out=6), as.integer64(seq(1, by=2, length.out=6)) )) -#! stopifnot(identical.integer64(seq.integer64(along.with=3:5), as.integer64(seq(along.with=3:5)) )) -#! stopifnot(identical.integer64(seq(as.integer64(1), to=-9), as.integer64(seq(1, to=-9)) )) -#! -#! message("Testing cbind and rbind") -#! stopifnot(identical.integer64( cbind(as.integer64(1:3), 1:3), {x <- rep(as.integer64(1:3), 2); dim(x)<-c(3,2);x})) -#! stopifnot(identical.integer64( rbind(as.integer64(1:3), 1:3), t({x <- rep(as.integer64(1:3), 2); dim(x)<-c(3,2);x}))) -#! -#! message("Testing coercion") -#! stopifnot(identical( as.double(as.integer64(c(NA, seq(0, 9, 0.25)))), as.double(as.integer(c(NA, seq(0, 9, 0.25)))))) -#! stopifnot(identical( as.character(as.integer64(c(NA, seq(0, 9, 0.25)))), as.character(as.integer(c(NA, seq(0, 9, 0.25)))))) -#! stopifnot(identical( as.integer(as.integer64(c(NA, seq(0, 9, 0.25)))), as.integer(c(NA, seq(0, 9, 0.25))))) -#! stopifnot(identical( as.logical(as.integer64(c(NA, seq(0, 9, 0.25)))), as.logical(as.integer(c(NA, seq(0, 9, 0.25)))))) -#! stopifnot(identical( as.integer(as.integer64(c(NA, FALSE, TRUE))), as.integer(c(NA, FALSE, TRUE)))) -#! stopifnot(identical( as.integer64(as.integer(as.integer64(-9:9))), as.integer64(-9:9))) -#! stopifnot(identical( as.integer64(as.double(as.integer64(-9:9))), as.integer64(-9:9))) -#! stopifnot(identical( as.integer64(as.character(as.integer64(-9:9))), as.integer64(-9:9))) -#! stopifnot(identical( as.integer64(as.character(lim.integer64())), lim.integer64())) -#! -#! message("-- testing logical operators --") -#! stopifnot(identical.integer64(!c(NA, -1:1), !c(as.integer64(NA), -1:1))) -#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)&rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))&as.integer64(rep(c(NA, -1:1), rep(4, 4))))) -#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)|rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))|as.integer64(rep(c(NA, -1:1), rep(4, 4))))) -#! stopifnot(identical.integer64(xor(rep(c(NA, -1:1), 4),rep(c(NA, -1:1), rep(4, 4))), xor(as.integer64(rep(c(NA, -1:1), 4)),as.integer64(rep(c(NA, -1:1), rep(4, 4)))))) -#! -#! message("-- testing comparison operators --") -#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)==rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))==as.integer64(rep(c(NA, -1:1), rep(4, 4))))) -#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)!=rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))!=as.integer64(rep(c(NA, -1:1), rep(4, 4))))) -#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)>rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))>as.integer64(rep(c(NA, -1:1), rep(4, 4))))) -#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)>=rep(c(NA, -1:1), rep(4, 4)), as.integer64(rep(c(NA, -1:1), 4))>=as.integer64(rep(c(NA, -1:1), rep(4, 4))))) -#! stopifnot(identical.integer64(rep(c(NA, -1:1), 4)