2026-05-10 21:46:37 +02:00
2026-04-28 08:08:37 +02:00
2026-05-10 21:46:37 +02:00
2026-05-10 21:46:37 +02:00
2026-05-10 21:46:37 +02:00
2026-04-28 09:22:55 +02:00
2026-04-17 16:01:37 +02:00
2026-04-17 16:05:39 +02:00
2026-05-10 21:46:37 +02:00
2026-05-10 01:51:35 +02:00

42_EXT_05_computorv1

ressources

install

this project uses submodules (maybe recursively), so either :

  • git clone --recurse-submodules <repo-url>
  • or, after cloning : git submodule update --init --recursive

steps

  1. lexer -> tokens types :

    • TOKEN_VARIABLE // x, y, etc.
    • TOKEN_NUMBER_INT // int
    • TOKEN_NUMBER_DOUBLE // double
    • TOKEN_POWER // ^ or **
    • TOKEN_SIGN_PLUS // +
    • TOKEN_SIGN_MINUS // -
    • TOKEN_FACTOR_MULT // *
    • TOKEN_FACTOR_DIV // / or :
    • TOKEN_EQUAL // =
    • END // null
  2. parser -> terms :

    • POSITION // left or righ from =
    • SIGN // + or -
    • COEFFICIENT // double
    • EXPONENT // double
  3. reduce -> polynom :

    • sign
    • coefficient
    • exponent
  4. print reduced form -> print reduced form -> if degree 1 :

    • if c = 0 -> print "any real is a solution"
    • if c != 0 -> print "no solution" -> if degree 2 :
    • print degree -> if degree 3 :
    • print degree
  5. solve -> degree 1 : -> ax + b = 0 <=> ax = -b <=> x = -b / a -> solution : - a; // double - b; // double - solution_gcd; // gcd(b, a) - solution_numerator; // -b / gcd - solution_denominator; // a / gcd - solution; // double (-b / a) -> degree 2 : -> discriminant : Δ = b² - 4ac -> Δ > 0 -> 2 solutions : x = ( -b / 2a ) +- ( √|Δ| / 2a ) -> Δ == 0 -> 1 solution : x = ( -b / 2a ) -> Δ < 0 -> 2 solutions : x = ( -b / 2a ) +- i( √|Δ| / 2a ) -> solution : - delta_sign; // + or - - delta_absolute; // |Δ| - delta_sqrt; // √|Δ|

     - first_term_gcd;          // gcd(b, 2a)
     - first_term_numerator;    // -b / gcd
     - first_term_denominator;  // 2a / gcd
     - first_term;              // double (-b / 2a)
    
     - second_term_gcd;         // gcd(√|Δ|, 2a)
     - second_term_numerator;   // √|Δ| / gcd
     - second_term_denominator; // 2a / gcd
     - second_term;             // double (√|Δ| / 2a)
    
     - double solution1;        // first_term + second_term
     - double solution2;        // first_term - second_term
    
  6. print solution


sqrt implementation

finding the square root of x

dichotomy method

the dichotomie method, or binary search, consist on dividing the range of research by 2 each time, and choosing the right one for the next iteration.

Ex :

     solution
        ↓
|------------------------------ 1. define range bound_1 : 0
|-----------------------------| 2. define range bound_2 : x
|--------------+--------------| 3. take mid : (bound_1 + bound_2) / 2
|--------------|-------ø------| 4. choose range bound : bound_1 or bound_2

---------------|--------------- 1. range bound_1 = mid
|--------------|--------------- 2. range bound_2 = chosen previous bound
|------+-------|--------------- 3. mid
|--ø---|-------|--------------- 4. choose range

-------|----------------------- 1. range bound_1 = mid
-------|-------|--------------- 2. range bound_2 = chosen previous bound
-------|---+---|--------------- 3. mid
-------|---|-ø-|--------------- 4. choose range

-----------|------------------- 1. range bound_1 = mid
-------|---|------------------- 2. range bound_2 = chosen previous bound
-------|-+-|------------------- 3. mid
-------|-|ø|------------------- 4. choose range

---------|--------------------- 1. range bound_1 = mid
-------|-|--------------------- 2. range bound_2 = chosen previous bound
-------|+|--------------------- 3. mid
-------ø|---------------------- 4. choose range

--------|---------------------- --> solution

NewtonRaphson method

it's like a self-correcting binary search, we get rid of the step "choose range", we use the formulae x/v to find the next range, with x being the number we are trying to get the sqaure root from, and v the value found at the previous step.

Ex :

     solution
        ↓
------------------------------| 1. define range bound_1 : v
--|---------------------------| 2. choose range bound_2 : x/v
--|-------------+-------------| 3. take mid : (v + x/v) / 2

----------------|-------------- 1. range bound_1 : v = mid
------|---------|-------------- 2. range bound_2 : x/v
------|----+----|-------------- 3. mid

-----------|------------------- 1. range bound_1 : v = mid
-|---------|------------------- 2. range bound_2 : x/v
-|----+----|------------------- 3. mid

------|------------------------ 1. range bound_1 : v = mid
------|-------|---------------- 2. range bound_2 : x/v
------|---+---|---------------- 3. mid

----------|-------------------- 1. range bound_1 : v = mid
------|---|-------------------- 2. range bound_2 : x/v
------|-+-|-------------------- 3. mid

--------|---------------------- --> solution

mathematical proof that each range is automatically in the right range :

  • if the value was higher than the answer, then new value is below old value, and vice versa
  • how ? :
    • define x, solution s = √x, and value v = (old_value + x / old_value) / 2
    • supposition : if v < s , then new_v > v, else new_v < v :
    • demonstration :
      1. if v < s : v < s <=> v < √x <=> v² < x (that's actually how we know that v < s) <=> v²/v < x/v <=> v < x/v -> and is s < x/v ? : v < s <=> v < √x <=> v² < x (as previously) <=> v² < x²/x <=> v² * x < x² <=> (v * √x)² < x² <=> v * √x < x <=> v * √x < v * x/v <=> √x < x/v -> so indeed : if v < √x, then v < √x < x/v == v < s < x/v -> conclusion, the new range < v , x/v > contains the solution
      2. the same demonstration works for v > s

here is a more intuitive demonstration, with x = 20 :

  1. show that if v² > x (== v > s) then v > s > x/v, and if v² < x (== v < s) then v < s < x/v : 1.1. for value too high v > s : 1.1.1 why v > x/v :
    • let's take initial value v = 5 :
    • is 5² the solution ? 5² == 25 -> so no, 5 is not the sqrt, it's too high
                v                   v²
           0   (5)   10   15   20   25
      v  : |----|----|----|----|----|
      x/v: |---|---|---|---|---| <----- squiz it, so the previous 5 portions fit the x = 20 size
           0  (4)  8   12  16  20
              x/v              x
      
    • the value of the new portion is 4, and we can visually see that it's lower than the previous portion 5
    • so : v > x/v 1.1.2 why s > x/v :
    • let's take the value v = 5 :
    • we already showed that it's too high, now we will see that x/v == 20/5 is too low :
                   v
              0   (5)   10   15   20   25
      v  :    |----|----|----|----|----|
      x/v:    |---|---|---|---|---|   <----- squizz
              0  *1  *2  *3  *4  *5       -> number of portions
              01234                       -> portion size
      (x/v)²: |---|---|---|---|
              0   4   8   12  16
      
    • the portion size is smaller than the number of portions, so it's too small to be the sqrt, indeed we visually see that this portion size x/v is a root of a smaller number : (x/v)² == 16
    • so : s > x/v 1.1.3. conclusion :
    • v > s
      
    • and v > x/v (<- this proof is not essential)
    • and s > x/v (<- we actually only need this proof)
    • so v > s > x/v

1.2. for value too high v < s : - this is the same demonstration but in other direction, let's just summarize it : - let's take initial value v = 4 : v v² 0 (4) 8 12 16 (1) v : |---|---|---|---| (2) x/v: |----|----|----|----| -----> stretch (3) 0 (5) 10 15 20 x/v x (4) 0 *1 *2 *3 *4 -> number of portions 012345 -> portion size (5) (x/v)²: |----|----|----|----|----| 0 5 10 15 20 25 - (1) : 4 is not the sqrt of x == 20, it's too smalle : (4² == 16) < 20 - (2) : stretch it, so the previous 4 portions fit the x = 20 size - (3) : the new portion x/v == 5, is more than v == 4, so v < x/v - (4) : portion size is bigger than number of portions, so it's too big to be the root - (5) : indeed, we see that the portion² == (x/v)² is bigger than x, so √x < x/v == s < x/v - so v < s < x/v

Description
No description provided
Readme 3.2 MiB
Languages
C 59.2%
Shell 37.5%
Makefile 3.3%