F#楼层功能不正确圆?

ole*_*ole 3 math f# floor

我有一个非常奇怪的问题.这是我简单的递归代码:

let float2cfrac x =
    let rec tofloat (lst : int list) (xi : float) =

        let qi = floor xi
        let ri = xi-qi

        printfn "%A %A %A %A" xi qi ri (1.0/ri)
        if ri > (floor 0.0) then          
            tofloat (lst @ [int qi]) (1.0/ri)
        else
            lst
    tofloat [] x
Run Code Online (Sandbox Code Playgroud)

我不会解释我的代码太多,因为我所拥有的问题似乎很基本.printfn将打印xi和qi,其中qi只是xi的底限.在查看输出时,看起来一旦软件达到xi的舍入数字,floor函数就会删除1,而不是什么都不做.

这是我的数字3.245的输出,它应该在几次计算后完成计算:

float2cfrac 3.245 ;;

3.245 3.0 0.245 4.081632653

4.081632653 4.0 0.08163265306 12.25

12.25 12.0 0.25 4.0

4.0 3.0 1.0 1.0 - 这里搞砸了.4.0的楼层应该是4,对吗?

1.0 1.0 4.035882739e-12 2.477772682e + 11

2.477772682e + 11 2.477772682e + 11 0.2112731934 4.733208147

4.733208147 4.0 0.7332081468 1.363869188

如果有人对此或某些建议有解释,我们将不胜感激!

Fyo*_*kin 7

一个众所周知的问题:浮点数具有有限的精度,因此通常不能依靠通过不同方法完成的相同计算来产生相同的结果.始终存在误差.

推论是您无法比较浮点数以获得严格的相等性.你必须把他们的差异与一些非常小的数字进行比较.

  • 另见http://floating-point-gui.de/.当4.0向下舍入到3.0时发生的事情是"4.0"值实际上已计算为3.9999999左右,原因是计算的前几个步骤中累积的舍入误差.`printfn`代码包括代码,可以直观地将3.9999999舍入到4.0,因为这是人们期望看到的,但是`floor`将其视为真正的3.9999999,因此它正确地舍入到3.0. (5认同)
  • `0.00000`与'0`相同.你应该做`ri> = 0.00001`. (3认同)
  • 您是否尝试过比较`abs(ri)> = Double.Epsilon`或您想要的精度.另请参阅[本文](https://www.codeproject.com/Articles/10143/Floating-Point-in-NET-part-Concepts-and-Formats). (3认同)