Floating point 如何为浮点数指定舍入模式?

Floating point 如何为浮点数指定舍入模式?,floating-point,rust,rounding,Floating Point,Rust,Rounding,我想将浮点数四舍五入到最接近的整数,当“最接近的整数”有一个平局时,向正无穷大进发 但是,round的文档说: 将中间箱从0.0取整 我还没有看到任何允许我改变舍入模式的东西,但一定有办法,对吗?看来Float::round的实现,至少对于f32和f64,将其转发到roundf32roundf64指令系统,它们本身是使用LLVM函数LLVM.round.f32和LLVM.round.f64实现的。遗憾的是,报告没有说明如何控制取整模式。LLVM引用中似乎也没有关于它的任何其他内容。我能找到的其他

我想将浮点数四舍五入到最接近的整数,当“最接近的整数”有一个平局时,向正无穷大进发

但是,
round
的文档说:

将中间箱从0.0取整


我还没有看到任何允许我改变舍入模式的东西,但一定有办法,对吗?

看来
Float::round
的实现,至少对于
f32
f64
,将其转发到
roundf32
roundf64
指令系统,它们本身是使用LLVM函数
LLVM.round.f32
LLVM.round.f64
实现的。遗憾的是,报告没有说明如何控制取整模式。LLVM引用中似乎也没有关于它的任何其他内容。我能找到的其他函数,甚至提到的舍入模式,要么指定了一个特定的舍入模式,要么说它是未定义的

我找不到任何可靠的信息。有人讨论了x86特定的内部函数,有人似乎讨论了一个假设的内部函数,以及它如何难以移植


盲目尝试:我会尝试编写一个C库来实现它,并链接到它。LLVM中似乎没有直接支持它。

恐怕我不知道Rust,但我写了以下内容(基于Arch Robinson对远离零的领带的类似顺序),您应该能够进行调整:

y = floor(x)
ifelse(x==y, y, copysign(floor(2*x-y),x))
快速解释正在发生的事情:

  • floor
    查找小于或等于
    x
    的最近整数
  • 如果
    y==x
    ,则
    x
    是一个整数,因此无需舍入:注意,这将捕获
    x
    的绝对值大于253的所有情况
  • floor(2*x-y)
    将给出所需的答案:
    2*x
    是准确的,我们不必担心步骤2导致的溢出。除
    -0.25
    外,所有情况下的减法都是精确的,这显然会给出正确的答案
  • copysign
    仅用于确保零具有正确的符号。如果你不为这些事烦恼,你可以把它放下
  • 步骤2和3可以由一个简单的分支代替:

    x-y < 0.5 ? y : y+1.0
    
    x-y<0.5?y:y+1.0
    

    但是如果我没记错的话,避免这里的分支会使代码更易于矢量化(这也是使用
    ifelse
    而不是
    if
    块的原因)。

    在IEEE 754浮点标准中没有“最接近+无限”舍入模式。即使Rust让您能够完全访问硬件的功能(可能是,也可能不是),它也不会提供这种舍入模式。你必须用手做四舍五入。中介绍了三种不同的方法,第二种方法至少应该易于修改,以便按照您想要的方式进行调整。@PascalCuoq oops!这就是我的假设!供日后参考,实际存在。谢谢!我对你的代码做了一些修改,使之生锈,它似乎通过了我的测试!
    x-y < 0.5 ? y : y+1.0