Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# floor function doesn't round properly?

Tags:

math

f#

floor

I have a super strange issue. Here's my simple piece of recursive code:

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

I'm not going to explain my code much, as the issue i'm having seems quite basic. The printfn will print xi and qi, where qi is simply the floor of xi. When looking at the output, it looks like once the software reaches a round number for xi, the floor function removes 1, instead of doing nothing.

Here's my output for the number 3.245, which should complete computing after just a few calculations:

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 - Here it gets messed up. Floor of 4.0 should be 4, right?

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

If anybody has an explanation for this or some sugguestions, it would be greatly appreciated!

like image 460
ole Avatar asked Jun 29 '26 10:06

ole


1 Answers

A super well known issue: floating-point numbers have finite precision, so you can't generally count on the same calculation done via different methods to produce the same result. There will always be a margin of error.

The corollary is that you can't compare floating-point numbers for strict equality. You have to take their difference and compare it to some very small number.

like image 163
Fyodor Soikin Avatar answered Jul 03 '26 11:07

Fyodor Soikin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!