fread 将大整数读取为 integer64,在算术表达式的情况下不会向上转换为双精度数

fread reads large integers as integer64, which are not upcasted to doubles in case of arithemetic expressions

当通过 fread 读取文件时,这些列可能会被读取为 integer64(正确如此),但是当它们与 numeric 相乘时,它们不会向上转换为 numeric(如 C++ 或 R 中的 integers)。虽然这是 bit64 包中记录的行为。但这并不直观,当数字相乘等时。integer64integer 相比表现不同。

此外,integer64 除以 integer 得到一个 numeric 变量。所以这个行为非常奇怪!

然后我们是否应该始终 fread 使用 colClasses = numeric 作为要在具有 numeric 等的算术表达式中使用的列?


    file contents
    x,y
    111,0.3
    2147483648,0.3

    > d <- fread(file)     
    > print(d$x*d$y)
            x       y
1:        111       0.3
2: 2147483648       0.3

> as.integer64(111) * 8e-2
integer64
[1] 9
> as.integer64(111) * 8 / 1e2
8.88

类似地,quantiles 和其他 R 函数与 integer64 的行为不正确。这个问题蔓延到所有使用 integer64 的 类,例如 nanotime

这是 bit64 包的记录行为,请参阅 ?bit64 中的算术精度和强制转换:

The fact that we introduce 64 bit long long integers – without introducing 128-bit long doubles – creates some subtle challenges

The multiplication operator * coerces its first argument to integer64 but allows its second argument to be also double: the second argument is internaly coerced to 'long double' and the result of the multiplication is returned as integer64

as.integer64(111) * 8e-2
integer64
[1] 9

The division / and power ^ operators also coerce their first argument to integer64 and coerce internally their second argument to 'long double', they return as double

as.integer64(111) * 8 / 1e2
8.88

为避免这种情况,您可以将 freadinteger64 参数设置为 "double"。小心使用,因为有 open issue.