计算整数位数

时间:2017-11-08 22:20:24

标签: r

我想计算数字向量x的小数点前的位数,数字大于或等于1.例如,如果向量是

x <- c(2.85, 356.01, 66.1, 210.0, 1445.11, 13.000)

我的代码应该返回一个包含整数1,3,2,3,4,2

的向量

有谁知道怎么做?

2 个答案:

答案 0 :(得分:14)

我想将评论留在评论中是没有意义的,但这些都适用于正数,对数字$ nvm list v6.11.5 -> v9.0.0 system default -> node (-> v9.0.0) node -> stable (-> v9.0.0) (default) stable -> 9.0 (-> v9.0.0) (default) $ nvm v6 具有相同的行为。

>= 1

如果您想要一个适用于负数的答案,请添加floor(log10(x)) + 1 nchar(trunc(x))

abs()

这些方法因输入前导0而异,例如floor(log10(abs(x))) + 1 nchar(trunc(abs(x))) -0.20.5332方法不会计算小数点前的log100方法会计算。选择对你的问题有意义的。

如果输入正好为0,则nchar(trunc())方法将不起作用,因此如果您想要使用该方法的强大解决方案,请将0作为一种特殊情况处理:

log10

答案 1 :(得分:0)

字符计数

对于小问题,我最喜欢nchar()解决方案,并对负值进行了一次修改:

nDigits <- function(x) nchar( trunc( abs(x) ) )

# Test
nDigits(100)
nDigits(-100)
# both have 3 digits

nDigits(3)
nDigits(-3)
nDigits(0.1)
nDigits(-0.1)
# all have 1 digit

nDigits(1 / .Machine$double.eps)
nDigits(-1 / .Machine$double.eps)
# both have 16 digits

以10为底的对数

如果要使对数解决方案有效,则需要考虑负值和0到1之间的值。对我来说,这种解决方案有点复杂:

nDigits2 <- function(x){

  truncX <- floor(abs(x))

  if(truncX != 0){
    floor(log10(truncX)) + 1
  } else {
    1
  }

}

速度表现

这里是微基准比较的输出(100,000次)。字符计数解决方案的代码更简单,但是更慢(减少了3-4倍):

对于大于1的整数(单位:纳秒):

          expr  min   lq      mean median   uq     max neval
  nDigits(100) 1711 2139 2569.2819   2566 2994 2234046 1e+05
 nDigits2(100)    0  428  861.5435    856  856 5670216 1e+05

对于很小的小数(单位:纳秒):

                           expr  min   lq     mean median   uq     max neval
 nDigits(1/.Machine$double.eps) 2994 4277 5066.321   4705 4705 4477928 1e+05
nDigits2(1/.Machine$double.eps)  428 1283 1588.382   1284 1711 2042458 1e+05