Code source du site TeacherCorner.lamdera.app, contenant une suite d'outils permettant d'automatiser la production de documents pédagogiques.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
TeacherCorner/src/Fraction.elm

206 lines
3.4 KiB

module Fraction exposing
( Erreur
, Fraction
, Resultat
, add
, den
, div
, estEntier
, exp
, frac
, inv
, mul
, neg
, num
, opp
, raw
, sub
, teX
)
import Arithmetic exposing (gcd)
type alias Fraction =
{ num : Int, den : Int }
type alias Resultat =
Result Erreur Fraction
type alias Erreur =
String
frac : Int -> Int -> Resultat
frac a b =
let
min =
1 - 2 ^ 31
max =
2 ^ 31 - 1
in
case b of
0 ->
Err "Division par zéro."
_ ->
if a > max || b > max || a < min || b < min then
Err "Certains calculs font intervenir des valeurs trop grandes pour être prises en charge."
else
Ok <| simplifier <| Fraction a b
simplifier : Fraction -> Fraction
simplifier a =
let
pgcd =
gcd a.num a.den
sgnDuDen =
if a.den < 0 then
-1
else
1
in
{ a
| num = sgnDuDen * (a.num // pgcd)
, den = sgnDuDen * (a.den // pgcd)
}
num a =
a.num
den a =
a.den
estEntier a =
a.den == 1
opp : (Fraction -> Fraction -> Resultat) -> Resultat -> Resultat -> Resultat
opp operation resultat1 resultat2 =
case ( resultat1, resultat2 ) of
( Ok fraction1, Ok fraction2 ) ->
operation fraction1 fraction2
( Err erreur, _ ) ->
Err erreur
( _, Err erreur ) ->
Err erreur
add : Fraction -> Fraction -> Resultat
add a b =
let
pgcd =
gcd a.den b.den
aDenBis =
a.den // pgcd
bDenBis =
b.den // pgcd
in
frac (a.num * bDenBis + b.num * aDenBis) (a.den * bDenBis)
neg : Fraction -> Fraction
neg a =
Fraction -a.num a.den
sub : Fraction -> Fraction -> Resultat
sub a b =
add a (neg b)
mul : Fraction -> Fraction -> Resultat
mul a b =
let
pgcd =
gcd a.num b.den
pgcdBis =
gcd b.num a.den
aNum =
a.num // pgcd
aDen =
a.den // pgcdBis
bNum =
b.num // pgcdBis
bDen =
b.den // pgcd
in
frac (aNum * bNum) (aDen * bDen)
inv : Fraction -> Resultat
inv a =
case a.num of
0 ->
Err "Division par zéro"
_ ->
Ok <| Fraction a.den a.num
div : Fraction -> Fraction -> Resultat
div a b =
Result.andThen (mul a) <| inv b
exp : Fraction -> Fraction -> Resultat
exp a b =
let
sgnDeA =
if a.num < 0 then
-1
else
1
sgnDeB =
if b.num < 0 then
-1
else
1
in
if b.den == 1 && b.num < 0 then
frac ((sgnDeA * a.den) ^ (sgnDeB * b.num)) ((sgnDeA * a.num) ^ (sgnDeB * b.num))
else if b.den == 1 then
frac (a.num ^ b.num) (a.den ^ b.num)
else
Err "Extraction de racine impossible"
teX a =
case a.den of
1 ->
String.fromInt a.num
_ ->
if a.num < 0 then
"-\\frac{" ++ String.fromInt -a.num ++ "}{" ++ String.fromInt a.den ++ "}"
else
"\\frac{" ++ String.fromInt a.num ++ "}{" ++ String.fromInt a.den ++ "}"
raw a =
"(" ++ String.fromInt a.num ++ "/" ++ String.fromInt a.den ++ ")"