sprintf 格式无效“%d" [英] sprintf invalid format '%d'

查看:138
本文介绍了sprintf 格式无效“%d"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这有效:

> sprintf('%d', c(1, 1.5))
[1] "1" "1"

这不会:

> sprintf('%d', c(1.5, 1))
Error in sprintf("%d", c(1.5, 1)) : 
  invalid format '%d'; use format %f, %e, %g or %a for numeric objects

为什么?

推荐答案

这实际上是一个非常有趣的问题.首先,%d 代表整数.如果可能,vector 参数会被回收,但如果它是 c(1.5, 1) 它将在 sprintf() 尝试替换 %d 时失败1.5(不是整数).

This is actually really interesting question. To start, %d stands for integer. The vector argument is recycled if possible but if it is c(1.5, 1) it will fail when sprintf() tries to replace %d with 1.5 (which is not integer).

我认为这可能与在 R 中 integer 和 double 都是数字模式的事实有关,例如:

I thought it might be related to the fact that in R both integer and double are numeric mode, for example:

storage.mode(c(1.5, 1))
# [1] "double"
storage.mode(c(1, 1.5))
# [1] "double"
mode(c(1,1.5))
# [1] "numeric"
mode(c(1.5,1))
# [1] "numeric"

因此两个向量都应该存储为双精度值.R 语言定义 的文档?数字:

Thus both vectors should be stored as double. More info about vector in R language definition and in the documentation for ? numeric:

潜在的混淆是 R 使用模式数字"来表示双精度或整数""

The potential confusion is that R has used mode "numeric" to mean ‘double or integer’"

我可能在 底层 C 代码中找到了解释这是怎么回事:

I might have found the lines in the underlying C code which explain what is going on:

if(TYPEOF(_this) == REALSXP) {
double r = REAL(_this)[0];
if((double)((int) r) == r)
_this = coerceVector(_this, INTSXP);

此代码执行以下操作:如果向量类型为 REALSXP(表示数字),则将向量的第一个成员转换为 double r.然后将 r 转换为整数,然后加倍,如果字节仍然相同,则将整个向量转换为 INTSXP.重要的是,这段代码只检查向量的第一个元素;如果该元素可以被强制为整数,则整个向量都被强制,否则代码会报错.

This code does the following: If the vector type is REALSXP (which means numeric) then convert first member of vector to double r. Then cast r as integer and then double and if bytes are still same convert whole vector as INTSXP. Importantly, this code only checks the first element of a vector; if that element can be coerced to integer, then the whole vector is coerced, otherwise the code gives an error.

为了测试这个假设,可以使用自定义的 sprintf() 编译 R,其中 double r = REAL(_this)[0]; 更改为 doubler = REAL(_this)[1]; 并测试 c(1.5, 1) 现在是否有效.

To test this hypothesis one could compile R with a custom sprintf() where double r = REAL(_this)[0]; is changed to double r = REAL(_this)[1]; and test whether c(1.5, 1) works now or not.

这篇关于sprintf 格式无效“%d"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆