Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Semrush - keyword research tool

Turn ChatGPT, Claude, Gemini, And CoPilot Into Your Personal Assistant, Business Coach, Content Creator, And More

AFFILIATE MARKETING Your all-in-one performance engine Manage affiliates, creators, and customer referrals in one unified platform—turning every partnership into measurable growth
Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Boost your online presence with premium web hosting and servers

Disclosure: My content contains affiliate links.

42,635 questions

55,370 answers

573 users

How to convert a decimal number to a rational number in Scala

1 Answer

0 votes
import scala.math.BigInt

/*
    DecimalToRational (Scala)
    -------------------------
    Converts a decimal number (given as a string) into an exact rational p/q.

    Why parse the string manually?
        • Scala has no built‑in rational type.
        • Double cannot preserve exact decimal digits.
        • Using strings + BigInt 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 (Euclid’s algorithm).
*/

case class Rational(numerator: BigInt, denominator: BigInt) {
  override def toString: String = s"$numerator/$denominator"
}

object DecimalToRational {

  // Euclid’s GCD algorithm
  def gcd(a: BigInt, b: BigInt): BigInt = {
    if (b == 0) a.abs else gcd(b, a % b)
  }

  // Convert decimal string to Rational
  def convertDecimalToRational(s: String): Rational = {
    val dotPos = s.indexOf('.')

    if (dotPos == -1) {
      // No decimal point → integer
      Rational(BigInt(s), BigInt(1))
    } else {
      val intPart  = s.substring(0, dotPos)
      val fracPart = s.substring(dotPos + 1)

      val integerValue    = BigInt(intPart)
      val fractionalValue = BigInt(fracPart)

      val digits = fracPart.length

      // denominator = 10^digits
      val denominator = BigInt(10).pow(digits)

      // numerator = integerValue * denominator + fractionalValue
      val numerator = integerValue * denominator + fractionalValue

      // Reduce fraction
      val g = gcd(numerator, denominator)

      Rational(numerator / g, denominator / g)
    }
  }

  def main(args: Array[String]): Unit = {
    val values = Seq(
      "3.5", "12.75", "0.125", "100.001",
      "7", "42.0", "0.333", "5.2"
    )

    values.foreach { v =>
      val r = convertDecimalToRational(v)
      println(s"$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

*/

 



answered Jul 23 by avibootz

Related questions

...