.NET Fiddle

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;

Rationnel r0 = new (2, 3),
          r1 = new (5, 2);
Console.WriteLine($"{r0}, {r1}"); // utilise Rationnel.ToString()
Console.WriteLine("{0}", new Rationnel(3, 6).Simplifier());
r0 = new (3, 6);
r1 = new (1, 2);
Console.WriteLine($"{r0} {(r0 == r1 ? "==" : "!=")} {r1}");
r0 = new (1, 4);
r1 = new (1, 2);
Console.WriteLine($"{r0} {(r0 == r1 ? "==" : "!=")} {r1}");
Console.WriteLine($"Symbolique : {r0 + r1}, décimal : {(float)(r0 + r1)}");
class DivisionParZéroException : Exception { }
class Rationnel : IEquatable<Rationnel>
{
   //
   // pour faciliter la simplification
   //
   private static int Pgcd(int a, int b) =>
      b != 0 ? Pgcd(a, a % b) : a;
   private int dénominateur;
   public int Numérateur { get; init; }
   public int Dénominateur
   {
      get => dénominateur;
      init
      {
         if (value == 0)
            throw new DivisionParZéroException();
         dénominateur = value;
      }
   }
   public Rationnel(int num, int dénom)
   {
      Numérateur = num;
      Dénominateur = dénom;
   }
   public Rationnel(int num)
   {
      Numérateur = num;
      Dénominateur = 1;
   }
   public Rationnel Simplifier()
   {
      int pgcd = Pgcd(Numérateur, Dénominateur);
      return new Rationnel(Numérateur / pgcd, Dénominateur / pgcd);
   }
   public static bool operator ==(Rationnel r0, Rationnel r1) =>
         r0.Equals(r1);
      //
      // écrire == oblige d'écrire !=
      //
      public static bool operator !=(Rationnel r0, Rationnel r1) =>
         !(r0 == r1);
      //
      // écrire == exige d'écrire Equals(object) pour qui
      // ne se limitera pas à C# sur la plateforme .NET
      // Notez que la surcharge polymorphique doit être explicite
      //
      public override bool Equals(object obj) =>
         obj is Rationnel r && Equals(r);
      //
      // IEquatable<Rationnel>
      //
      public bool Equals(Rationnel r)
      {
         Rationnel r0 = Simplifier(),
                   r1 = r.Simplifier();
         return r0.Numérateur == r1.Numérateur &&
                r0.Dénominateur == r1.Dénominateur;
      }
      //
      // écrire Equals(object) mène à écrire GetHashCode()... >soupir!<
      // Notez que la surcharge polymorphique doit être explicite
      //
      public override int GetHashCode() =>
         Numérateur.GetHashCode() ^ Dénominateur.GetHashCode(); // bof
// ...
      public static bool operator <(Rationnel r0, Rationnel r1) =>
         r0.Numérateur * r1.Dénominateur < r1.Numérateur * r0.Dénominateur;
      public static bool operator >(Rationnel r0, Rationnel r1) =>
         r1 < r0;
      public static bool operator <=(Rationnel r0, Rationnel r1) =>
         !(r1 < r0);
      public static bool operator >=(Rationnel r0, Rationnel r1) =>
         !(r0 < r1);
// ...
      public static Rationnel operator +(Rationnel r0, Rationnel r1) =>
         new
         (
            r0.Numérateur * r1.Dénominateur + r1.Numérateur * r0.Dénominateur,
            r0.Dénominateur * r1.Dénominateur
         );
// ...
      //
      // Traiter un Rationnel comme une string
      //
      public override string ToString() =>
         $"{Numérateur}/{Dénominateur}";
// ...
      //
      // Traiter un Rationnel comme un float ou comme un double
      //
      static public explicit operator float(Rationnel r) =>
         ((float)r.Numérateur) / r.Dénominateur;
      static public explicit operator double(Rationnel r) =>
         ((double)r.Numérateur) / r.Dénominateur;
   }
;