Задача:
Дано два целых числа A и B. нужно вывести строку, которая является
результатом деления A / B. Если в дроби есть период, то его выделить в скобки.
Например:
1/3 = 0.(3)
1/8 = 0.125
4/3 = 1.(3)
1/11 = 0.(09)
Решение:
using System;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// 1/3 = 0.(3)
// 1/8 = 0.125
// 4/3 = 1.(3)
// 1/11 = 0.(09)
// 1/12 = 0.08 *(3) * возвращает как непериодическую дробь
// 1/13 = 0,(076923)
// 1/14 = 0,07(142857)
// 1/15 = 0.06 *(6)
// 1/16 = 0.0625
// 1/17 = 0,(0588235294117647)
// 1/18 = 0.05 *(5)
// 1/19 = 0,(052631578947368421)
string str = getPeriod(4, 3);
Console.WriteLine(str);
}
public static string getPeriod(int numerator, int denominator)
{
StringBuilder s = new StringBuilder();
// частное в десятичном виде
float x = (float)numerator / denominator;
// целая часть
int dev = numerator / denominator;
if (numerator < 1)
return "Делитель меньше 1. Не наш случай";
else if (numerator == denominator)
// правильная дробь
s.Append(dev.ToString());
else if (numerator > denominator)
{
// неправильная дробь. вычисляем дробную часть
float rest = x - numerator / denominator;
s.Append(dev.ToString());
if (rest > 0)
{
// остаток > 0, уменьшаем numerator и ищем период
numerator -= dev * denominator;
s.Append("," + GetFraction(numerator, denominator));
}
}
// правильная дробь: 0 < numerator < denominator
else if (denominator % 2 == 0 || denominator % 5 == 0)
// дробь конечная, т.е. периода нет или период начинается
//не с первого знака после запятой. например, 1/12
//**********************************************
//http://www.ega-math.narod.ru/Quant/Fracti.htm
//**********************************************
/*Если натуральное число m не делится на 2 и на 5,
то период десятичной дроби, равной 1/m, начинается
сразу после запятой. Его длина равна наименьшему n,
при котором число, составленное из n девяток делится
на m. Сам период равен частному от деления этого
числа из девяток на m, записанному как n-значное
число (возможно, с нулями в начале). Если m не
делится и на 3, то можно также сказать, что длина
периода равна номеру первого репьюнита, делящегося на m. */
s.Append(x.ToString());
else
// остаток деления (дробная часть). период начинается с 1-го знака
s.Append(dev.ToString() + "," + GetFraction(numerator, denominator));
return s.ToString();
}
static string GetFraction(int numerator, int denominator)
{
/*******************************************************************
http://stackoverflow.com/questions/8946310/how-to-know-the-repeating
-decimal-in-a-fraction
********************************************************************/
int[] digits = new int[denominator];
int k = 0, n = numerator;
do
{
n *= 10;
digits[k++] = n / denominator;
n = n % denominator;
}
while (n != numerator);
int[] period = new int[k];
for (n = 0; n < k; ++n)
{
period[n] = digits[n];
}
//*******************************************************************
StringBuilder s = new StringBuilder();
if (period.Length > 0)
{
s.Append("(");
for (int i = 0; i <= period.Length - 1; i++)
{
s.Append(period[i]);
}
s.Append(")");
}
return s.ToString();
}
}
}