r - 在 R 中实现 nextafter 功能

标签 r floating-point

R中是否有任何功能实现,以便可以从给定的浮点数中获取下一个可表示的浮点数。这将类似于 nextafter C标准库中的函数。方案如number + .Machine$double.eps一般不工作。

最佳答案

不,但有两种方法可以做到:

使用 C

如果您想要 nextafter() 的确切功能函数,您可以编写一个 C 函数作为函数的接口(interface),从而满足以下两个约束:

  • 该函数不返回值。所有工作都是作为“副作用”完成的(改变参数的值)。
  • 所有参数都是指针。甚至标量也是 R 中的向量(长度为 1)。

  • 然后应该将该函数编译为共享库:
    R CMD SHLIB foo.c
    

    对于类 UNIX 操作系统。可以使用 dyn.load("foo.so") 调用共享库.然后,您可以使用 .C() 从 R 内部调用该函数。功能
    .C("foo", ...)
    

    从 R 调用 C 的更深入处理是 here .

    使用 R
    number + .Machine$double.eps是要走的路,但您必须考虑边缘情况,例如 if x - y < .Machine$double.eps或者如果 x == y .我会这样写函数:
    nextafter <- function(x, y){
      # Appropriate type checking and bounds checking goes here
      delta = y - x
      if(x > 0){
        factor = 2^floor(log2(x)) + ifelse(x >= 4, 1, 0)
          } else if (x < 0) {
        factor = 65
      }
      if (delta > .Machine$double.eps){
        return(x + factor * .Machine$double.eps)
      } else if (delta < .Machine$double.eps){
        return(x - factor * .Machine$double.eps)
      } else {
        return(x)
      }
    }
    

    现在,与 C 不同,如果要检查整数,可以在同一个函数中执行此操作,但需要根据类型更改增量。

    更新
    对于大于 2 的数字,前面的代码没有按预期执行。有一个因子需要乘以 .Machine$double.eps。使其足够大以导致数字不同。它与最接近的 2 加 1 的幂有关。您可以通过以下代码了解它是如何工作的:
    n <- -100
    factor <- vector('numeric', 100)
    for(i in 1:n){
      j = 0
      while(TRUE){
        j = j + 1
        if(i - j * .Machine$double.eps != i) break()
      }
      factor[i] = j
    }  
    

    关于r - 在 R 中实现 nextafter 功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22047238/

    相关文章:

    math - float 学有问题吗?

    c++ - gcc 的 __float128 float 是否考虑了当前的舍入模式?

    c++ - 浮点比较

    opencv - 将 Mat 对象的类型从 CV_32F 更改为 CV_8U

    r - 这是预期的行为吗

    r - 在点图(ggplot)中添加线交叉因子

    css - Shinydashboard - 根据所选选项卡更改背景

    R - 更改列表中元素的顺序

    r - separate_rows 在结果周围生成引号

    c++ - float 的整数部分中的 10 进制数字的最大位数是多少