Open In App

Midy’s theorem

Last Updated : 24 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

According to Midy’s theorem, if the period of a repeating decimal for a / p              , where p is prime and a / p              is a reduced fraction, has an even number of digits, then dividing the repeating portion into halves and adding gives a string of 9s.

Examples :

a = 1 and p = 7 
1/7 = 0.14285714285.. 
So 1/7 is a repeating decimal with 142857 being repeated. Now, according to the theorem, it has even number of repeating digits i.e. 142857. Further if we divide this into two halves, we get 142 and 857. Thus, on adding these two, we get 999 which is string of 9s and matches our theorem. 
a = 2 and p = 11 
2/11 = 0.18181818181.. 
Here, repeating decimal is 18. Now this is even in number therefore 1+8 = 9 which again shows the validity of Midy’s theorem.

Given numerator and denominator, the task is to find if the resultant floating point number follows Midy’s theorem or not.
 

Approach : 
Let us simulate the process of converting fraction to decimal. Let us look at the part where we have already figured out the integer part which is floor(numerator/denominator). Now we are left with ( remainder = numerator%denominator ) / denominator. 
If you remember the process of converting to decimal, at each step we do the following : 

  1. Multiply the remainder by 10.
  2. Append remainder / denominator to result.
  3. Remainder = remainder % denominator.

At any moment, if remainder becomes 0, we are done.
However, when there is a recurring sequence, remainder never becomes 0. For example if you look at 1/3, the remainder never becomes 0.

Below is one important observation : 
If we start with remainder ‘rem’ and if the remainder repeats at any point of time, the digits between the two occurrence of ‘rem’ keep repeating.
So the idea is to store seen remainders in a map. Whenever a remainder repeats, we return the sequence before the next occurrence.

Below is the implementation of Midy’s theorem : 

C++

// C++ implementation as a
// proof of the Midy's theorem
#include <bits/stdc++.h>
using namespace std;
  
// Returns repeating sequence of a fraction.
// If repeating sequence doesn't exits,
// then returns -1
string fractionToDecimal(int numerator, int denominator)
{
    string res;
  
    /* Create a map to store already seen remainders
       remainder is used as key and its position in
       result is stored as value. Note that we need
       position for cases like 1/6. In this case,
       the recurring sequence doesn't start from first
       remainder. */
    map<int, int> mp;
    mp.clear();
      
    // Find first remainder
    int rem = numerator % denominator;
  
    // Keep finding remainder until either remainder
    // becomes 0 or repeats
    while ((rem != 0) && (mp.find(rem) == mp.end())) 
    {
        // Store this remainder
        mp[rem] = res.length();
  
        // Multiply remainder with 10
        rem = rem * 10;
  
        // Append rem / denr to result
        int res_part = rem / denominator;
        res += to_string(res_part);
  
        // Update remainder
        rem = rem % denominator;
    }
    return (rem == 0) ? "-1" : res.substr(mp[rem]);
}
  
// Checks whether a number is prime or not
bool isPrime(int n)
{
    for (int i = 2; i <= n / 2; i++)     
        if (n % i == 0)
            return false;
   return true;
}
  
// If all conditions are met,
// it proves Midy's theorem
void Midys(string str, int n)
{
    int l = str.length();
    int part1 = 0, part2 = 0;
    if (!isPrime(n))    
    
        cout << "Denominator is not prime, "
             << "thus Midy's theorem is not applicable";
    }
    else if (l % 2 == 0) 
    {
        for (int i = 0; i < l / 2; i++) 
        {
            part1 = part1 * 10 + (str[i] - '0');
            part2 = part2 * 10 + (str[l / 2 + i] - '0');
        }
        cout << part1 << " + " << part2 << " = " 
             << (part1 + part2) << endl;
        cout << "Midy's theorem holds!";
    }
    else 
    {
        cout << "The repeating decimal is of odd length "
             << "thus Midy's theorem is not applicable";
    }
}
  
// Driver code
int main()
{
    int numr = 2, denr = 11;
    string res = fractionToDecimal(numr, denr);
    if (res == "-1")
        cout << "The fraction does not have repeating decimal";
    else {
        cout << "Repeating decimal = " << res << endl;
        Midys(res, denr);
    }
    return 0;
}

                    

Java

// Java implementation as a
// proof of the Midy's theorem
import java.util.*;
  
class GFG{
  
// Returns repeating sequence of a fraction.
// If repeating sequence doesn't exits,
// then returns -1
static String fractionToDecimal(int numerator, 
                                int denominator)
{
    String res = "";
  
    /* Create a map to store already seen remainders
    remainder is used as key and its position in
    result is stored as value. Note that we need
    position for cases like 1/6. In this case,
    the recurring sequence doesn't start from first
    remainder. */
    HashMap<Integer, Integer> mp = new HashMap<>();
      
    // Find first remainder
    int rem = numerator % denominator;
  
    // Keep finding remainder until either remainder
    // becomes 0 or repeats
    while ((rem != 0) && !mp.containsKey(rem))
    {
          
        // Store this remainder
        mp.put(rem, res.length());
  
        // Multiply remainder with 10
        rem = rem * 10;
  
        // Append rem / denr to result
        int res_part = rem / denominator;
        res += res_part + "";
  
        // Update remainder
        rem = rem % denominator;
    }
      
    return (rem == 0) ? "-1" : res.substring(mp.get(rem));
}
  
// Checks whether a number is prime or not
static boolean isPrime(int n)
{
    for(int i = 2; i <= n / 2; i++)
        if (n % i == 0)
            return false;
              
    return true;
}
  
// If all conditions are met,
// it proves Midy's theorem
static void Midys(String str, int n)
{
    int l = str.length();
    int part1 = 0, part2 = 0;
      
    if (!isPrime(n))    
    
        System.out.print("Denominator is not prime, "
                         "thus Midy's theorem is not " +
                         "applicable");
    }
    else if (l % 2 == 0
    {
        for(int i = 0; i < l / 2; i++) 
        {
            part1 = part1 * 10 + (str.charAt(i) - '0');
            part2 = part2 * 10 + (str.charAt(l / 2 + i) - '0');
        }
        System.out.println(part1 + " + " + part2 +
                           " = " + (part1 + part2));
        System.out.print("Midy's theorem holds!");
    }
    else 
    {
        System.out.print("The repeating decimal is "
                         "of odd length thus Midy's "+
                         "theorem is not applicable");
    }
}
  
// Driver code
public static void main(String []args)
{
    int numr = 2, denr = 11;
    String res = fractionToDecimal(numr, denr);
      
    if (res == "-1")
        System.out.print("The fraction does not " +
                         "have repeating decimal");
    else
    {
        System.out.println("Repeating decimal = " + res);
        Midys(res, denr);
    }
}
}
  
// This code is contributed by rutvik_56

                    

Python3

# Python3 implementation as a
# proof of the Midy's theorem
  
# Returns repeating sequence of a fraction.
# If repeating sequence doesn't exits,
# then returns -1
def fractionToDecimal(numerator, denominator):
    res = ""
  
    ''' Create a map to store already seen remainders
       remainder is used as key and its position in
       result is stored as value. Note that we need
       position for cases like 1/6. In this case,
       the recurring sequence doesn't start from first
       remainder. '''
    mp = dict()
  
    # Find first remainder
    rem = numerator % denominator
  
    # Keep finding remainder until either remainder
    # becomes 0 or repeats
    while ((rem != 0) and (rem not in mp)):
  
        # Store this remainder
        mp[rem] = len(res)
  
        # Multiply remainder with 10
        rem = rem * 10
  
        # Append rem / denr to result
        res_part = (rem // denominator)
        res += str(res_part)
  
        # Update remainder
        rem = rem % denominator
  
    return ["-1", res[mp[rem]:]][rem != 0]
  
  
# Checks whether a number is prime or not
def isPrime(n):
    for i in range(2, 1 + n // 2):
        if (n % i == 0):
            return False
    return True
  
  
# If all conditions are met,
# it proves Midy's theorem
def Midys(str, n):
  
    l = len(str)
    part1 = 0
    part2 = 0
    if (not isPrime(n)):
        print("Denominator is not prime, thus Midy's theorem is not applicable")
  
    elif (l % 2 == 0):
  
        for i in range(l // 2):
  
            part1 = part1 * 10 + int(str[i])
            part2 = part2 * 10 + int(str[(l // 2) + i])
  
        print(part1, "+", part2, "=", (part1 + part2))
        print("Midy's theorem holds!")
  
    else:
  
        print(
            "The repeating decimal is of odd length thus Midy's theorem is not applicable")
  
  
# Driver code
numr = 2
denr = 11
res = fractionToDecimal(numr, denr)
if (res == "-1"):
    print("The fraction does not have repeating decimal")
  
else:
    print("Repeating decimal =", res)
    Midys(res, denr)
  
  
# This code is contributed by phasing17.

                    

C#

// C# implementation as a
// proof of the Midy's theorem
using System;
using System.Collections;
using System.Collections.Generic;
  
class GFG{
  
// Returns repeating sequence of a fraction.
// If repeating sequence doesn't exits,
// then returns -1
static String fractionToDecimal(int numerator, 
                                int denominator)
{
    String res = "";
  
    /* Create a map to store already seen remainders
    remainder is used as key and its position in
    result is stored as value. Note that we need
    position for cases like 1/6. In this case,
    the recurring sequence doesn't start from first
    remainder. */
    Dictionary<int,int> mp = new Dictionary<int,int>();
      
    // Find first remainder
    int rem = numerator % denominator;
  
    // Keep finding remainder until either remainder
    // becomes 0 or repeats
    while ((rem != 0) && !mp.ContainsKey(rem))
    {
          
        // Store this remainder
        mp[rem]= res.Length;
  
        // Multiply remainder with 10
        rem = rem * 10;
  
        // Append rem / denr to result
        int res_part = rem / denominator;
        res += res_part + "";
  
        // Update remainder
        rem = rem % denominator;
    }
      
    return (rem == 0) ? "-1" : res.Substring(mp[rem]);
}
  
// Checks whether a number is prime or not
static bool isPrime(int n)
{
    for(int i = 2; i <= n / 2; i++)
        if (n % i == 0)
            return false;           
    return true;
}
  
// If all conditions are met,
// it proves Midy's theorem
static void Midys(String str, int n)
{
    int l = str.Length;
    int part1 = 0, part2 = 0;   
    if (!isPrime(n))    
    
        Console.Write("Denominator is not prime, "
                         "thus Midy's theorem is not " +
                         "applicable");
    }
    else if (l % 2 == 0) 
    {
        for(int i = 0; i < l / 2; i++) 
        {
            part1 = part1 * 10 + (str[i] - '0');
            part2 = part2 * 10 + (str[l / 2 + i] - '0');
        }
        Console.WriteLine(part1 + " + " + part2 +
                           " = " + (part1 + part2));
        Console.Write("Midy's theorem holds!");
    }
    else 
    {
        Console.Write("The repeating decimal is "
                         "of odd length thus Midy's "+
                         "theorem is not applicable");
    }
}
  
// Driver code
public static void Main(string []args)
{
    int numr = 2, denr = 11;
    string res = fractionToDecimal(numr, denr);
      
    if (res == "-1")
        Console.Write("The fraction does not " +
                         "have repeating decimal");
    else
    {
        Console.WriteLine("Repeating decimal = " + res);
        Midys(res, denr);
    }
}
}
  
// This code is contributed by pratham76.

                    

Javascript

// JavaScript implementation as a
// proof of the Midy's theorem
  
  
// Returns repeating sequence of a fraction.
// If repeating sequence doesn't exits,
// then returns -1
function fractionToDecimal(numerator, denominator)
{
    let res = "";
  
    /* Create a map to store already seen remainders
       remainder is used as key and its position in
       result is stored as value. Note that we need
       position for cases like 1/6. In this case,
       the recurring sequence doesn't start from first
       remainder. */
    let mp = {};
      
    // Find first remainder
    let rem = numerator % denominator;
  
    // Keep finding remainder until either remainder
    // becomes 0 or repeats
    while ((rem != 0) && (!mp.hasOwnProperty(rem))) 
    {
        // Store this remainder
        mp[rem] = res.length;
  
        // Multiply remainder with 10
        rem = rem * 10;
  
        // Append rem / denr to result
        let res_part = Math.floor(rem / denominator);
        res += (res_part.toString());
  
        // Update remainder
        rem = rem % denominator;
    }
    return (rem == 0) ? "-1" : res.substr(mp[rem]);
}
  
// Checks whether a number is prime or not
function isPrime(n)
{
    for (var i = 2; i <= n / 2; i++)     
        if (n % i == 0)
            return false;
   return true;
}
  
// If all conditions are met,
// it proves Midy's theorem
function Midys(str, n)
{
    var l = str.length;
    var part1 = 0, part2 = 0;
    if (!isPrime(n))    
    
        console.log("Denominator is not prime, thus Midy's theorem is not applicable");
    }
    else if (l % 2 == 0) 
    {
        for (var i = 0; i < l / 2; i++) 
        {
            part1 = part1 * 10 + parseInt(str[i]);
            part2 = part2 * 10 + parseInt(str[(Math.floor(l / 2) + i)]);
        }
        console.log(part1 + " + " + part2 + " = " + (part1 + part2));
        console.log("Midy's theorem holds!");
    }
    else 
    {
        console.log("The repeating decimal is of odd length thus Midy's theorem is not applicable");
    }
}
  
// Driver code
let numr = 2;
let denr = 11;
let res = fractionToDecimal(numr, denr);
if (res == "-1")
    console.log("The fraction does not have repeating decimal");
  
else 
{
    console.log("Repeating decimal = " + res);
    Midys(res, denr);
}
  
// This code is contributed by phasing17.

                    

Output : 

Repeating decimal = 18
1 + 8 = 9
Midy's theorem holds!

Time Complexity: O(n*log(n))

Auxiliary Space: O(n)
More about Midy’s theorem can be found on 
http://www.kurims.kyoto-u.ac.jp/EMIS/journals/INTEGERS/papers/h2/h2.pdf 
http://digitalcommons.unl.edu/cgi/viewcontent.cgi?article=1047&context=mathfacpub
 



Similar Reads

Extended Midy's theorem
According to Midy's theorem, if the period of a repeating decimal for [Tex]a / p [/Tex], where p is prime and [Tex]a / p [/Tex]is a reduced fraction, has an even number of digits, then dividing the repeating portion into halves and adding gives a string of 9s. For example 1/7 = 0.14285714285.. is a repeating decimal with 142857 being repeated. Now,
13 min read
Cook–Levin theorem or Cook's theorem
In computational complexity theory, the Cook–Levin theorem, also known as Cook's theorem, states that the Boolean satisfiability problem is NP-complete. That is, it is in NP, and any problem in NP can be reduced in polynomial time by a deterministic Turing machine to the Boolean satisfiability problem. Stephen Arthur Cook and L.A. Levin in 1973 ind
4 min read
Compute nCr % p | Set 4 (Chinese Remainder theorem with Lucas Theorem)
Given three numbers n, r and p, the task is to compute the value of nCr % p. Note: p is a square-free number and the largest prime factor of p ≤ 50. Examples: Input: n = 10, r = 2, p = 13Output: 6Explanation: 10C2 is 45 and 45 % 13= 6 Input: n = 6, r = 2, p = 13Output: 2 Approach: We have already discussed several other approaches of this problem.
10 min read
Fermat's little theorem
Fermat's little theorem states that if p is a prime number, then for any integer a, the number a p - a is an integer multiple of p. Here p is a prime number ap ≡ a (mod p). Special Case: If a is not divisible by p, Fermat's little theorem is equivalent to the statement that a p-1-1 is an integer multiple of p. ap-1 ≡ 1 (mod p) OR ap-1 % p = 1 Here
8 min read
Nicomachus’s Theorem (Sum of k-th group of odd positive numbers)
The positive odd numbers in ascending order as 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, .... and grouped as (1), (3, 5), (7, 9, 11), (13, 15, 17, 19), .... and so on. Thus, the first group is (1), the second group is (3, 5) and the third group is (7, 9, 11), etc. in general, the kth group contains the next k elements of the sequence. Given k, find the su
7 min read
Advanced master theorem for divide and conquer recurrences
The Master Theorem is a tool used to solve recurrence relations that arise in the analysis of divide-and-conquer algorithms. The Master Theorem provides a systematic way of solving recurrence relations of the form: T(n) = aT(n/b) + f(n) where a, b, and f(n) are positive functions and n is the size of the problem. The Master Theorem provides conditi
5 min read
Nicomachus's Theorem
Nicomachus's Theorem states that sum of cubes of first n natural numbers is equal to squares of natural number sum.[Tex]1^{3}+2^{3}+3^{3}+\cdots +n^{3}=\left(1+2+3+\cdots +n\right)^{2} [/Tex]In other words[Tex]1^{3}+2^{3}+3^{3}+\cdots +n^{3}=\left(n*(n+1)/2)^{2} [/Tex]Or we can say that the sum is equal to square of n-th triangular number.Mathemati
3 min read
Euclid Euler Theorem
According to Euclid Euler Theorem, a perfect number which is even, can be represented in the form [Tex](2^n - 1)*(2^n / 2) )) [/Tex]where n is a prime number and [Tex]2^n - 1 [/Tex]is a Mersenne prime number. It is a product of a power of 2 with a Mersenne prime number. This theorem establishes a connection between a Mersenne prime and an even perf
10 min read
Hardy-Ramanujan Theorem
Hardy Ramanujam theorem states that the number of prime factors of n will approximately be log(log(n)) for most natural numbers nExamples : 5192 has 2 distinct prime factors and log(log(5192)) = 2.1615 51242183 has 3 distinct prime facts and log(log(51242183)) = 2.8765 As the statement quotes, it is only an approximation. There are counter examples
6 min read
Lagrange's four square theorem
Lagrange's Four Square Theorem states that every natural number can be written as sum of squares of four non negative integers. For eg. [Tex]1 = 0^2 + 0^2 + 0^2 +1^2 [/Tex]Similarly [Tex]2 = 0^2 + 0^2 + 1^2 +1^2 [/Tex]Similarly for any [Tex]n\in N, n = a^2 + b^2 + c^2 + d^2 where \ a, b, c, d, \in N \cup \{0\} [/Tex] The above identity may be deriv
8 min read