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.
206 lines
4.1 KiB
206 lines
4.1 KiB
module Fraction exposing
|
|
( Erreur
|
|
, Fraction
|
|
, Resultat
|
|
, asciiMath
|
|
, denominateur
|
|
, difference
|
|
, estEntier
|
|
, exp
|
|
, fraction
|
|
, inverse
|
|
, map2
|
|
, numerateur
|
|
, oppose
|
|
, produit
|
|
, quotient
|
|
, somme
|
|
, teX
|
|
)
|
|
|
|
import Arithmetic exposing (gcd)
|
|
|
|
|
|
type alias Fraction =
|
|
{ numerateur : Int, denominateur : Int }
|
|
|
|
|
|
type alias Resultat =
|
|
Result Erreur Fraction
|
|
|
|
|
|
type alias Erreur =
|
|
String
|
|
|
|
|
|
fraction : Int -> Int -> Resultat
|
|
fraction 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.numerateur a.denominateur
|
|
|
|
sgnDuDen =
|
|
if a.denominateur < 0 then
|
|
-1
|
|
|
|
else
|
|
1
|
|
in
|
|
{ a
|
|
| numerateur = sgnDuDen * (a.numerateur // pgcd)
|
|
, denominateur = sgnDuDen * (a.denominateur // pgcd)
|
|
}
|
|
|
|
|
|
numerateur a =
|
|
a.numerateur
|
|
|
|
|
|
denominateur a =
|
|
a.denominateur
|
|
|
|
|
|
estEntier a =
|
|
a.denominateur == 1
|
|
|
|
|
|
map2 : (Fraction -> Fraction -> Resultat) -> Resultat -> Resultat -> Resultat
|
|
map2 operation resultat1 resultat2 =
|
|
case ( resultat1, resultat2 ) of
|
|
( Ok fractiontion1, Ok fractiontion2 ) ->
|
|
operation fractiontion1 fractiontion2
|
|
|
|
( Err erreur, _ ) ->
|
|
Err erreur
|
|
|
|
( _, Err erreur ) ->
|
|
Err erreur
|
|
|
|
|
|
somme : Fraction -> Fraction -> Resultat
|
|
somme a b =
|
|
let
|
|
pgcd =
|
|
gcd a.denominateur b.denominateur
|
|
|
|
aDenBis =
|
|
a.denominateur // pgcd
|
|
|
|
bDenBis =
|
|
b.denominateur // pgcd
|
|
in
|
|
fraction (a.numerateur * bDenBis + b.numerateur * aDenBis) (a.denominateur * bDenBis)
|
|
|
|
|
|
oppose : Fraction -> Fraction
|
|
oppose a =
|
|
Fraction -a.numerateur a.denominateur
|
|
|
|
|
|
difference : Fraction -> Fraction -> Resultat
|
|
difference a b =
|
|
somme a (oppose b)
|
|
|
|
|
|
produit : Fraction -> Fraction -> Resultat
|
|
produit a b =
|
|
let
|
|
pgcd =
|
|
gcd a.numerateur b.denominateur
|
|
|
|
pgcdBis =
|
|
gcd b.numerateur a.denominateur
|
|
|
|
aNum =
|
|
a.numerateur // pgcd
|
|
|
|
aDen =
|
|
a.denominateur // pgcdBis
|
|
|
|
bNum =
|
|
b.numerateur // pgcdBis
|
|
|
|
bDen =
|
|
b.denominateur // pgcd
|
|
in
|
|
fraction (aNum * bNum) (aDen * bDen)
|
|
|
|
|
|
inverse : Fraction -> Resultat
|
|
inverse a =
|
|
case a.numerateur of
|
|
0 ->
|
|
Err "Division par zéro"
|
|
|
|
_ ->
|
|
Ok <| Fraction a.denominateur a.numerateur
|
|
|
|
|
|
quotient : Fraction -> Fraction -> Resultat
|
|
quotient a b =
|
|
Result.andThen (produit a) <| inverse b
|
|
|
|
|
|
exp : Fraction -> Fraction -> Resultat
|
|
exp a b =
|
|
let
|
|
sgnDeA =
|
|
if a.numerateur < 0 then
|
|
-1
|
|
|
|
else
|
|
1
|
|
|
|
sgnDeB =
|
|
if b.numerateur < 0 then
|
|
-1
|
|
|
|
else
|
|
1
|
|
in
|
|
if b.denominateur == 1 && b.numerateur < 0 then
|
|
fraction ((sgnDeA * a.denominateur) ^ (sgnDeB * b.numerateur)) ((sgnDeA * a.numerateur) ^ (sgnDeB * b.numerateur))
|
|
|
|
else if b.denominateur == 1 then
|
|
fraction (a.numerateur ^ b.numerateur) (a.denominateur ^ b.numerateur)
|
|
|
|
else
|
|
Err "L'extraction de racine n'est pas disponible pour les nombres écrits sous forme fractiontionnaire."
|
|
|
|
|
|
teX a =
|
|
case a.denominateur of
|
|
1 ->
|
|
String.fromInt a.numerateur
|
|
|
|
_ ->
|
|
if a.numerateur < 0 then
|
|
"-\\fraction{" ++ String.fromInt -a.numerateur ++ "}{" ++ String.fromInt a.denominateur ++ "}"
|
|
|
|
else
|
|
"\\fraction{" ++ String.fromInt a.numerateur ++ "}{" ++ String.fromInt a.denominateur ++ "}"
|
|
|
|
|
|
asciiMath a =
|
|
"(" ++ String.fromInt a.numerateur ++ "/" ++ String.fromInt a.denominateur ++ ")"
|
|
|