989*_*989 6 floating-point r numeric
R FAQ指出:
唯一可以用R的数字类型精确表示的数字是分母为2的幂的整数和分数。所有其他数字在内部舍入为(通常)53个二进制数字精度。
R使用IEEE 754双精度浮点数,即
总计为64位。
对于数字0.1,R表示
sprintf("%.60f", 0.1)
[1] "0.100000000000000005551115123125782702118158340454101562500000"
Run Code Online (Sandbox Code Playgroud)
Double(IEEE754双精度64位)为我们提供了以下二进制表示形式0.1:
00111111 10111001 10011001 10011001 10011001 10011001 10011001 10011010
Run Code Online (Sandbox Code Playgroud)
我们如何在R中获得此表示形式,以及它与sprintf本示例中给出的输出有何关系?
@chux在评论中提出的问题的答案是“是”。R支持%a格式:
sprintf("%a", 0.1)
#> [1] "0x1.999999999999ap-4"
Run Code Online (Sandbox Code Playgroud)
如果要访问基础位模式,则必须将double解释为64位整数。为此,可以通过Rcpp使用C ++:
Rcpp::cppFunction('void print_hex(double x) {
uint64_t y;
static_assert(sizeof x == sizeof y, "Size does not match!");
std::memcpy(&y, &x, sizeof y);
Rcpp::Rcout << std::hex << y << std::endl;
}', plugins = "cpp11", includes = "#include <cstdint>")
print_hex(0.1)
#> 3fb999999999999a
Run Code Online (Sandbox Code Playgroud)
此十六进制表示形式与您的二进制表示形式相同。如何获得小数表示形式?
总共得出2 ^?56×7,205,759,403,792,794:
sprintf("%.60f", 2^-56 * 7205759403792794)
#> [1] "0.100000000000000005551115123125782702118158340454101562500000"
Run Code Online (Sandbox Code Playgroud)