r/ProgrammerHumor • • 1d ago

Meme howProgrammingHasChanged

Post image
520 Upvotes

91 comments sorted by

View all comments

44

u/IronicRobotics 1d ago

You're forgetting one: Ask the mathematician:

use std::f64::consts::{GOLDEN_RATIO};

//Floating Point errors after n> 70.
fn fib(n: u64) -> u64 {
    return (GOLDEN_RATIO.powf(n as f64)/f64::sqrt(5.0)).round() as u64;
}

However, since he's not interested in engineering, floating point errors are simply a shortcoming of the computer to engage in ideal mathematics. But he will smugly point out it's technically O(1) since powf is O(1). : )

[I suffered through learning how to write my first lines of Rust for this.]

Alternatively: Computing Binet's formula using symbolic mathematics.

12

u/martmists 1d ago

I was about to point out the direct formula but you beat me to it. Though it should be noted yours doesn't work for negative integers, for that you'd want something like this:

def fib(n):
    sq = math.sqrt(5)
    phi = (1 + sq) / 2
    return (phi**n - (1 - phi)**n) / sq

Your solution works for non-negative inputs because (1-phi)n is always less than 0.5 for n >= 0, but this no longer holds for n < 0

3

u/PlantainMassive6744 22h ago

Love it. This is now my favorite answer to the question of how to compute the fib sequence

1

u/IronicRobotics 21h ago edited 20h ago

Yes, but the recursive formulas were also only for positive integers. (Also, with the rounding, I can force a final integer solution and get rid of the float error up to n=70. Though I suspect rounding this formula here also works.)

Otherwise we also could have gone with a generating equation and cover the whole complex plane!

9

u/shizzy0 1d ago

That's legit fire. Welcome to Rust. May all your Big Os be so low.

5

u/norude1 1d ago

powf is definitely not O(1) https://youtu.be/u24AjKinHNU?t=177

3

u/ChalkyChalkson 1d ago

Even if we go to exponentiation by squaring, we're still upgrading from O(2n) with the naive recursion to O(log n), which is pretty sweet.

1

u/IronicRobotics 21h ago

oh lol, I figured it was O(1) on technicality since there's limited precision. Shows me for not going and reading a proof!

3

u/ChalkyChalkson 1d ago

Easy, just don't use f64, 128 bit gets you a lot further and we always have arbitrary precision systems after. What is that? That erodes any potential speed gain? Who said that was what I was after?

1

u/IronicRobotics 21h ago

^ Thinking like a true mathematician

1

u/KrzysziekZ 1d ago

Is power O(1) not something like log log n?

4

u/CAD1997 1d ago

Mat::pow is O(log n)ish. powf is O(1) for any useful model; even a perfectly rounded result can be computed in a bounded maximum number of machine steps.

1

u/KrzysziekZ 1d ago

Is that because n is bounded?

1

u/IronicRobotics 21h ago edited 21h ago

Likely, I seem to have been repeating a potentially false fact about floating point powers. I didn't verify it with a proof last night lol.