/// <summary> /// Получить пропись числа с согласованной единицей измерения. /// </summary> /// <param name="число"> Число должно быть целым, неотрицательным. </param> /// <param name="еи"></param> /// <param name="result"> Сюда записывается результат. </param> /// <returns> <paramref name="result"/> </returns> /// <exception cref="ArgumentException"> /// Если число меньше нуля или не целое. /// </exception> public static StringBuilder Пропись(decimal число, IЕдиницаИзмерения еи, StringBuilder result) { string error = ПроверитьЧисло(число); if (error != null) { throw new ArgumentException(error, "число"); } // Целочисленные версии работают в разы быстрее, чем decimal. if (число <= uint.MaxValue) { Пропись((uint)число, еи, result); } else if (число <= ulong.MaxValue) { Пропись((ulong)число, еи, result); } else { MyStringBuilder mySb = new MyStringBuilder(result); decimal div1000 = Math.Floor(число / 1000); ПрописьСтаршихКлассов(div1000, 0, mySb); ПрописьКласса((uint)(число - div1000 * 1000), еи, mySb); } return(result); }
/// <summary> /// Получить пропись числа с согласованной единицей измерения. /// </summary> /// <param name="число"> /// Число должно быть целым, неотрицательным, не большим <see cref="MaxDouble"/>. /// </param> /// <param name="еи"></param> /// <param name="result"> Сюда записывается результат. </param> /// <exception cref="ArgumentException"> /// Если число меньше нуля, не целое или больше <see cref="MaxDouble"/>. /// </exception> /// <returns> <paramref name="result"/> </returns> /// <remarks> /// float по умолчанию преобразуется к double, поэтому нет перегрузки для float. /// В результате ошибок округления возможно расхождение цифр прописи и /// строки, выдаваемой double.ToString ("R"), начиная с 17 значащей цифры. /// </remarks> public static StringBuilder Пропись(double число, IЕдиницаИзмерения еи, StringBuilder result) { string error = ПроверитьЧисло(число); if (error != null) { throw new ArgumentException(error, "число"); } if (число <= uint.MaxValue) { Пропись((uint)число, еи, result); } else if (число <= ulong.MaxValue) { // Пропись с ulong выполняется в среднем в 2 раза быстрее. Пропись((ulong)число, еи, result); } else { MyStringBuilder mySb = new MyStringBuilder(result); double div1000 = Math.Floor(число / 1000); ПрописьСтаршихКлассов(div1000, 0, mySb); ПрописьКласса((uint)(число - div1000 * 1000), еи, mySb); } return(result); }
/// <summary> /// Формирует запись класса с названием, например, /// "125 тысяч", "15 рублей". /// Для 0 записывает только единицу измерения в род.мн. /// </summary> private static void ПрописьКласса(uint числоДо999, IЕдиницаИзмерения класс, MyStringBuilder sb) { uint числоЕдиниц = числоДо999 % 10; uint числоДесятков = (числоДо999 / 10) % 10; uint числоСотен = (числоДо999 / 100) % 10; sb.Append(Сотни [числоСотен]); if ((числоДо999 % 100) != 0) { Десятки [числоДесятков].Пропись(sb, числоЕдиниц, класс.одЧисло); } // Добавить название класса в нужной форме. sb.Append(Согласовать(класс, числоДо999)); }
/// <summary> /// Получить пропись числа с согласованной единицей измерения. /// </summary> /// <returns> <paramref name="result"/> </returns> public static StringBuilder Пропись(ulong число, IЕдиницаИзмерения еи, StringBuilder result) { if (число <= uint.MaxValue) { Пропись((uint)число, еи, result); } else { MyStringBuilder mySb = new MyStringBuilder(result); ulong div1000 = число / 1000; ПрописьСтаршихКлассов(div1000, 0, mySb); ПрописьКласса((uint)(число - div1000 * 1000), еи, mySb); } return(result); }
/// <summary> /// Получить пропись числа с согласованной единицей измерения. /// </summary> /// <returns> <paramref name="result"/> </returns> public static StringBuilder Пропись(uint число, IЕдиницаИзмерения еи, StringBuilder result) { MyStringBuilder mySb = new MyStringBuilder(result); if (число == 0) { mySb.Append("ноль"); mySb.Append(еи.одМнож); } else { uint div1000 = число / 1000; ПрописьСтаршихКлассов(div1000, 0, mySb); ПрописьКласса(число - div1000 * 1000, еи, mySb); } return(result); }
/// <summary> /// Согласовать название единицы измерения с числом. /// Например, согласование единицы (рубль, рубля, рублей) /// с числом 23 даёт "рубля", а с числом 25 - "рублей". /// </summary> public static string Согласовать(IЕдиницаИзмерения единицаИзмерения, uint число) { uint числоЕдиниц = число % 10; uint числоДесятков = (число / 10) % 10; if (числоДесятков == 1) { return(единицаИзмерения.одМнож); } switch (числоЕдиниц) { case 1: return(единицаИзмерения.ИменЕдин); case 2: case 3: case 4: return(единицаИзмерения.одЕдин); default: return(единицаИзмерения.одМнож); } }
/// <summary> /// Формирует запись класса с названием, например, /// "125 тысяч", "15 рублей". /// Для 0 записывает только единицу измерения в род.мн. /// </summary> private static void ПрописьКласса(uint числоДо999, IЕдиницаИзмерения класс, MyStringBuilder sb) { uint числоЕдиниц = числоДо999 % 10; uint числоДесятков = (числоДо999 / 10) % 10; uint числоСотен = (числоДо999 / 100) % 10; sb.Append(Сотни[числоСотен]); if ((числоДо999 % 100) != 0) { Десятки[числоДесятков].Propis(sb, числоЕдиниц, класс.РодЧисло); } // Добавить название класса в нужной форме. sb.Append(Согласовать(класс, числоДо999)); }
/// <summary> /// Согласовать название единицы измерения с числом. /// Например, согласование единицы (рубль, рубля, рублей) /// с числом 23 даёт "рубля", а с числом 25 - "рублей". /// </summary> public static string Согласовать(IЕдиницаИзмерения единицаИзмерения, decimal число) { return Согласовать(единицаИзмерения, (uint)(число % 100)); }
/// <summary> /// Возвращает пропись числа. /// </summary> public static string Пропись(uint число, IЕдиницаИзмерения еи, Заглавные заглавные) { return(ApplyCaps(Пропись(число, еи, new StringBuilder()), заглавные)); }
/// <summary> /// Возвращает пропись числа строчными буквами. /// </summary> public static string Propis(uint число, IЕдиницаИзмерения еи) { return Propis(число, еи, Заглавные.Нет); }
/// <summary> /// Получить пропись числа с согласованной единицей измерения. /// </summary> /// <returns> <paramref name="result"/> </returns> public static StringBuilder Propis(uint число, IЕдиницаИзмерения еи, StringBuilder result) { MyStringBuilder mySb = new MyStringBuilder(result); if (число == 0) { mySb.Append("ноль"); mySb.Append(еи.РодМнож); } else { uint div1000 = число / 1000; ПрописьСтаршихКлассов(div1000, 0, mySb); ПрописьКласса(число - div1000 * 1000, еи, mySb); } return result; }
/// <summary> /// Получить пропись числа с согласованной единицей измерения. /// </summary> /// <returns> <paramref name="result"/> </returns> public static StringBuilder Propis(ulong число, IЕдиницаИзмерения еи, StringBuilder result) { if (число <= uint.MaxValue) { Propis((uint)число, еи, result); } else { MyStringBuilder mySb = new MyStringBuilder(result); ulong div1000 = число / 1000; ПрописьСтаршихКлассов(div1000, 0, mySb); ПрописьКласса((uint)(число - div1000 * 1000), еи, mySb); } return result.Replace(result.ToString().Substring(0, 1), result.ToString().Substring(0, 1).ToUpper(),0,1); }
/// <summary> /// Получить пропись числа с согласованной единицей измерения. /// </summary> /// <param name="число"> /// Число должно быть целым, неотрицательным, не большим <see cref="MaxDouble"/>. /// </param> /// <param name="еи"></param> /// <param name="result"> Сюда записывается результат. </param> /// <exception cref="ArgumentException"> /// Если число меньше нуля, не целое или больше <see cref="MaxDouble"/>. /// </exception> /// <returns> <paramref name="result"/> </returns> /// <remarks> /// float по умолчанию преобразуется к double, поэтому нет перегрузки для float. /// В результате ошибок округления возможно расхождение цифр прописи и /// строки, выдаваемой double.ToString ("R"), начиная с 17 значащей цифры. /// </remarks> public static StringBuilder Propis(double число, IЕдиницаИзмерения еи, StringBuilder result) { string error = ПроверитьЧисло(число); if (error != null) throw new ArgumentException(error, "число"); if (число < 0) { result.Append("минус "); число = Convert.ToDouble(число.ToString().Remove(0, 1)); } if (число <= uint.MaxValue) { Propis((uint)число, еи, result); } else if (число <= ulong.MaxValue) { // Propis с ulong выполняется в среднем в 2 раза быстрее. Propis((ulong)число, еи, result); } else { MyStringBuilder mySb = new MyStringBuilder(result); double div1000 = Math.Floor(число / 1000); ПрописьСтаршихКлассов(div1000, 0, mySb); ПрописьКласса((uint)(число - div1000 * 1000), еи, mySb); } return result.Replace(result.ToString().Substring(0, 1), result.ToString().Substring(0, 1).ToUpper(),0,1); }
/// <summary> /// Получить пропись числа с согласованной единицей измерения. /// </summary> /// <param name="число"> Число должно быть целым, неотрицательным. </param> /// <param name="еи"></param> /// <param name="result"> Сюда записывается результат. </param> /// <returns> <paramref name="result"/> </returns> /// <exception cref="ArgumentException"> /// Если число меньше нуля или не целое. /// </exception> public static StringBuilder Propis(decimal число, IЕдиницаИзмерения еи, StringBuilder result) { string error = ПроверитьЧисло(число); if (error != null) throw new ArgumentException(error, "число"); if (число < 0) { result.Append("минус "); число = Convert.ToDecimal(число.ToString().Remove(0, 1)); } // Целочисленные версии работают в разы быстрее, чем decimal. if (число <= uint.MaxValue) { Propis((uint)число, еи, result); } else if (число <= ulong.MaxValue) { Propis((ulong)число, еи, result); } else { MyStringBuilder mySb = new MyStringBuilder(result); decimal div1000 = Math.Floor(число / 1000); ПрописьСтаршихКлассов(div1000, 0, mySb); ПрописьКласса((uint)(число - div1000 * 1000), еи, mySb); } return result.Replace(result.ToString().Substring(0,1), result.ToString().Substring(0,1).ToUpper(),0,1); }
/// <summary> </summary> public Currency(IЕдиницаИзмерения основная, IЕдиницаИзмерения дробная) { this.основная = основная; this.дробная = дробная; }
/// <summary> /// Согласовать название единицы измерения с числом. /// Например, согласование единицы (рубль, рубля, рублей) /// с числом 23 даёт "рубля", а с числом 25 - "рублей". /// </summary> public static string Согласовать(IЕдиницаИзмерения единицаИзмерения, decimal число) { return(Согласовать(единицаИзмерения, (uint)(число % 100))); }
/// <summary> /// Возвращает пропись числа строчными буквами. /// </summary> public static string Пропись(uint число, IЕдиницаИзмерения еи) { return(Пропись(число, еи, Заглавные.Нет)); }
/// <summary> /// Возвращает пропись числа. /// </summary> public static string Propis(uint число, IЕдиницаИзмерения еи, Заглавные заглавные) { return ApplyCaps(Propis(число, еи, new StringBuilder()), заглавные); }
/// <summary> </summary> public Валюта(IЕдиницаИзмерения основная, IЕдиницаИзмерения дробная) { this.основная = основная; this.дробная = дробная; }
/// <summary> /// Согласовать название единицы измерения с числом. /// Например, согласование единицы (рубль, рубля, рублей) /// с числом 23 даёт "рубля", а с числом 25 - "рублей". /// </summary> public static string Согласовать(IЕдиницаИзмерения единицаИзмерения, uint число) { uint числоЕдиниц = число % 10; uint числоДесятков = (число / 10) % 10; if (числоДесятков == 1) return единицаИзмерения.РодМнож; switch (числоЕдиниц) { case 1: return единицаИзмерения.ИменЕдин; case 2: case 3: case 4: return единицаИзмерения.РодЕдин; default: return единицаИзмерения.РодМнож; } }