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
包中记录的行为。但这并不直观,当数字相乘等时。integer64
与 integer
相比表现不同。
此外,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
为避免这种情况,您可以将 fread
的 integer64
参数设置为 "double"
。小心使用,因为有 open issue.
当通过 fread
读取文件时,这些列可能会被读取为 integer64(正确如此),但是当它们与 numeric
相乘时,它们不会向上转换为 numeric
(如 C++ 或 R
中的 integers
)。虽然这是 bit64
包中记录的行为。但这并不直观,当数字相乘等时。integer64
与 integer
相比表现不同。
此外,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
为避免这种情况,您可以将 fread
的 integer64
参数设置为 "double"
。小心使用,因为有 open issue.