Перейти к содержанию

Округление: различия между версиями

Материал из Химсофт Вики
Строка 73: Строка 73:
===Итоговый вариант на С#===
===Итоговый вариант на С#===
<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
public class Rounding
/// <summary>
///    В отличие от стандартных функций, поддерживает работу с отрицательными разрядами и округление до значащих цифр.
/// </summary>
/// <param name="value">Исходное число для обработки;</param>
/// <param name="digits">
///    - при Mode = 1 - количество знаков после запятой (положительное) или до запятой (отрицательное);<br/>
///    - при Mode = 0 - количество значащих цифр; 
/// </param>
/// <param name="mode">
///    — <see cref="RoundMode.ToDecimalPlace"/> — десятичное округление;<br/>
///    — <see cref="RoundMode.ToSignificantPlace"/> — значащие цифры
/// </param>
/// <returns>Строковое представление числа, округленного по заданным параметрам</returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static string RoundBase(double value, int digits, RoundMode mode)
{
{
    public string RoundBase(double value, int digits, RoundMode mode)
if (value == 0)  
    {
return "0";
        if (value == 0)  
            return "0";


        double result;
double result;
        switch (mode)
switch (mode)
        {
{
            case RoundMode.ToDecimalPlace:
case RoundMode.ToDecimalPlace:
                double factor = Math.Pow(10, digits);
double factor = Math.Pow(10, digits);
                result = Math.Round(value * factor, 0, MidpointRounding.AwayFromZero) / factor;
result = Math.Round(value * factor, 0, MidpointRounding.AwayFromZero) / factor;
                return result.ToString("F" + Math.Max(0, digits));
return result.ToString("F" + Math.Max(0, digits));
            case RoundMode.ToSignificantPlace:
case RoundMode.ToSignificantPlace:
                double scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(value))) + 1 - digits);
double scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(value))) + 1 - digits);
                result = Math.Round(value / scale, 0, MidpointRounding.AwayFromZero) * scale;
result = Math.Round(value / scale, 0, MidpointRounding.AwayFromZero) * scale;
                return result.ToString("G");
return result.ToString("G");
            default:
default:
                throw new ArgumentOutOfRangeException(nameof(mode), "Некорректный режим округления");
throw new ArgumentOutOfRangeException(nameof(mode), Localization.InvalidRoundMode);
        }
}
    }
   
    public string RoundBase(double value, int digits, int mode) => RoundBase(value, digits, (RoundMode)mode);
}
}
</syntaxhighlight>
</syntaxhighlight>

Версия от 07:51, 20 октября 2026

Rounding.RoundBase()

Предназначена для гибкого округления числовых значений.

В отличие от стандартных функций, она поддерживает работу с отрицательными разрядами и округление до значащих цифр.

Входные параметры

  • value (Double) - исходное число для обработки;
  • digits (Object)
    • при Mode = 1 - количество знаков после запятой (положительное) или до запятой (отрицательное);
    • при Mode = 0 - количество значащих цифр;
  • mode (Object) - режим работы:
    • 1 (ToDecimalPlace) - десятичное округление;
    • 0 (ToSignificantPlace) - значащие цифры.

Выходные параметры

  • String - возвращает строковое представление числа.

Алгоритм

Функция работает по методу Away From Zero (округление от нуля).

Режим 1 (десятичное округление):

  • вычисляется множитель;
  • число умножается на множитель, округляется до целого и делится обратно;
  • при положительном n результат форматируется с фиксированным количеством нулей после запятой.

Режим 0 (значащие цифры):

  • определяется порядок числа через десятичный логарифм;
  • вычисляется масштабный коэффициент, чтобы оставить ровно n цифр;
  • число масштабируется, округляется и возвращается в исходный порядок;
  • результат преобразуется в компактную строку (удаляются лишние нули в конце).

Примеры использования внутри ячейки

Исходное значение Синтаксис в соответствии с формулой =Code.Rounding.RoundBase(x, n, m) Результат
12345
=Code.Rounding.RoundBase(ReportItems!variable.Value, 2, 1)
12345,00
12345.00
=Code.Rounding.RoundBase(ReportItems!variable.Value, 0, 1)
12345
12345.01
=Code.Rounding.RoundBase(ReportItems!variable.Value, -2, 1)
12300
555.55
=Code.Rounding.RoundBase(ReportItems!variable.Value, 1, 0)
600

Примеры использования во вкладке Scripts

Return New Triteia.Rounding().RoundBase(variable, 2, 1)

или

Dim rounder As New Triteia.Rounding()

Return rounder.RoundBase(variable, 2, 1)

Итоговый вариант на С#

/// <summary>
///     В отличие от стандартных функций, поддерживает работу с отрицательными разрядами и округление до значащих цифр.
/// </summary>
/// <param name="value">Исходное число для обработки;</param>
/// <param name="digits">
///     - при Mode = 1 - количество знаков после запятой (положительное) или до запятой (отрицательное);<br/>
///     - при Mode = 0 - количество значащих цифр;  
/// </param>
/// <param name="mode">
///     — <see cref="RoundMode.ToDecimalPlace"/> — десятичное округление;<br/>
///     — <see cref="RoundMode.ToSignificantPlace"/> — значащие цифры
/// </param>
/// <returns>Строковое представление числа, округленного по заданным параметрам</returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static string RoundBase(double value, int digits, RoundMode mode)
{
	if (value == 0) 
		return "0";

	double result;
	switch (mode)
	{
		case RoundMode.ToDecimalPlace:
			double factor = Math.Pow(10, digits);
			result = Math.Round(value * factor, 0, MidpointRounding.AwayFromZero) / factor;
			return result.ToString("F" + Math.Max(0, digits));
		case RoundMode.ToSignificantPlace:
			double scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(value))) + 1 - digits);
			result = Math.Round(value / scale, 0, MidpointRounding.AwayFromZero) * scale;
			return result.ToString("G");
		default:
			throw new ArgumentOutOfRangeException(nameof(mode), Localization.InvalidRoundMode);
	}
}