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
3.4 KiB
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 ++ ")"
|
|
|