using System;
using System.Numerics;
/*
DecimalToRational
-----------------
Converts a decimal number (given as a string) into an exact rational number p/q.
Why parse the string?
• C# has no built‑in rational type.
• double/float cannot preserve exact decimal digits.
• Using strings + BigInteger ensures perfect accuracy.
Algorithm:
1. Look for a decimal point.
2. If none → integer → numerator = n, denominator = 1.
3. Otherwise:
Example: "12.345"
integer part = 12
fractional part = 345
digits = 3
numerator = integer_part * 10^digits + fractional_part
denominator = 10^digits
4. Reduce using gcd (BigInteger.GreatestCommonDivisor).
*/
class DecimalToRational
{
// Simple rational container
struct Rational
{
public BigInteger Numerator;
public BigInteger Denominator;
public override string ToString() {
return $"{Numerator}/{Denominator}";
}
}
// Convert decimal string to Rational
static Rational ConvertDecimalToRational(string s)
{
int dotPos = s.IndexOf('.');
if (dotPos == -1) {
// No decimal point → integer
BigInteger num = BigInteger.Parse(s);
return new Rational { Numerator = num, Denominator = BigInteger.One };
}
// Split into integer and fractional parts
string intPart = s.Substring(0, dotPos);
string fracPart = s.Substring(dotPos + 1);
BigInteger integerValue = BigInteger.Parse(intPart);
BigInteger fractionalValue = BigInteger.Parse(fracPart);
int digits = fracPart.Length;
// Build denominator = 10^digits
BigInteger denominator = BigInteger.Pow(10, digits);
// Build numerator
BigInteger numerator = integerValue * denominator + fractionalValue;
// Reduce using gcd
BigInteger g = BigInteger.GreatestCommonDivisor(numerator, denominator);
numerator /= g;
denominator /= g;
return new Rational { Numerator = numerator, Denominator = denominator };
}
static void Main()
{
string[] values =
{
"3.5", "12.75", "0.125", "100.001",
"7", "42.0", "0.333", "5.2"
};
foreach (var v in values) {
Rational r = ConvertDecimalToRational(v);
Console.WriteLine($"{v} -> {r}");
}
}
}
/*
run:
3.5 -> 7/2
12.75 -> 51/4
0.125 -> 1/8
100.001 -> 100001/1000
7 -> 7/1
42.0 -> 42/1
0.333 -> 333/1000
5.2 -> 26/5
*/