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

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

Материал из Химсофт Вики
Новая страница: «==Rounding.RoundBase()== Предназначена для гибкого округления числовых значений. В отличие от стандартных функций, она поддерживает работу с отрицательными разрядами и округление до значащих цифр. ===Входные параметры=== *<code>value</code> (''Double'') - исходное число для об...»
 
 
(не показано 20 промежуточных версий этого же участника)
Строка 1: Строка 1:
==Rounding.RoundBase()==
Функция <code>Rounding.RoundBase()</code> - предназначена для гибкого округления числовых значений.


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


В отличие от стандартных функций, она поддерживает работу с отрицательными разрядами и округление до значащих цифр.
==Входные параметры==
 
===Входные параметры===
*<code>value</code> (''Double'') - исходное число для обработки;
*<code>value</code> (''Double'') - исходное число для обработки;
*<code>digits</code> (''Object'')  
*<code>digits</code> (''Object'')  
Строка 14: Строка 12:
**<code>0</code> (''ToSignificantPlace'') - значащие цифры.
**<code>0</code> (''ToSignificantPlace'') - значащие цифры.


===Выходные параметры===
==Выходные параметры==
*<code>String</code> - возвращает строковое представление числа.
*<code>String</code> - возвращает строковое представление числа.


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


Строка 31: Строка 29:
*результат преобразуется в компактную строку (удаляются лишние нули в конце).
*результат преобразуется в компактную строку (удаляются лишние нули в конце).


===Примеры использования внутри ячейки===
==Использование в выражениях==
 
''Принципы использования:''


{|class="wikitable" style="margin:auto; background-color: #fff; width:100%"  
{|class="wikitable" style="margin:auto; background-color: #fff; width:100%"  
|-
|-
!Исходное значение
!Исходное значение
!Синтаксис в соответствии с формулой <code>=Code.Rounding.RoundBase(x, n, m)</code>
!Синтаксис в соответствии с формулой
!Результат
!Результат
|-
|-
|style="text-align:right"|12345
|style="text-align:right"|12345
|<syntaxhighlight lang="vb">=Code.Rounding.RoundBase(ReportItems!variable.Value, 2, 1)</syntaxhighlight>
|<syntaxhighlight lang="C#">[Rounding.RoundBase([DataBase.field], 2, 1)]</syntaxhighlight>
|style="text-align:right"|12345,00
|style="text-align:right"|12345,00
|-
|-
|style="text-align:right"|12345.00
|style="text-align:right"|12345.00
|<syntaxhighlight lang="vb">=Code.Rounding.RoundBase(ReportItems!variable.Value, 0, 1)</syntaxhighlight>
|<syntaxhighlight lang="C#">[Rounding.RoundBase([DataBase.field], 0, 1)]</syntaxhighlight>
|style="text-align:right"|12345
|style="text-align:right"|12345
|-
|-
|style="text-align:right"|12345.01
|style="text-align:right"|12345.01
|<syntaxhighlight lang="vb">=Code.Rounding.RoundBase(ReportItems!variable.Value, -2, 1)</syntaxhighlight>
|<syntaxhighlight lang="C#">[Rounding.RoundBase([DataBase.field], -2, 1)]</syntaxhighlight>
|style="text-align:right"|12300
|style="text-align:right"|12300
|-
|-
|style="text-align:right"|555.55
|style="text-align:right"|555.55
|<syntaxhighlight lang="vb">=Code.Rounding.RoundBase(ReportItems!variable.Value, 1, 0)</syntaxhighlight>
|<syntaxhighlight lang="C#">[Rounding.RoundBase([DataBase.field], 1, 0)]</syntaxhighlight>
|style="text-align:right"|600
|style="text-align:right"|600
|-
|-
|}
|}


===Примеры использования во вкладке <code>Scripts</code>===
''Примеры:''
<syntaxhighlight lang="C#">
// A_2
[Rounding.RoundBase(ToDouble([Main.table_size]) / 1000, 0, 1)]
 
// R_3
[ResultOrDash(Rounding.RoundBase(First([Main.min_avg]), 2, 1))]


<syntaxhighlight lang="vb">
Return New Triteia.Rounding().RoundBase(variable, 2, 1)
</syntaxhighlight>
</syntaxhighlight>


или
==Использование во вкладке кода==


<syntaxhighlight lang="vb">
<syntaxhighlight lang="C#">
Dim rounder As New Triteia.Rounding()
// NG_2
string result = Rounding.RoundBase(normDouble, scaleInt, 1);


Return rounder.RoundBase(variable, 2, 1)
// NG_2
finalResult4 = Rounding.RoundBase(storage.Results[0], 2, 1);
 
// NG_2
return Rounding.RoundBase(firstNum, 2, 1) + " (" + Rounding.RoundBase(secondNum, 0, 1) + ")";
</syntaxhighlight>
</syntaxhighlight>


===Предварительный вариант на VB.NET===
==Подключение==
<syntaxhighlight lang="vb">
Public Function RoundBase(ByVal xValue As Double, ByVal nDigits As Integer, ByVal mMode As Integer) As String
If xValue = 0 Then Return "0"
'Проверка аргумента nDigits, является ли пустым, остутствующим в БД или пустой строкой
Dim nDigitsFlag As Boolean = True
If nDigits Is Nothing OrElse IsDBNull(nDigits) OrElse String.IsNullOrEmpty(nDigits.ToString().Trim()) Then
nDigitsFlag = False
End If
'Проверка аргумента mMode, является ли пустым, остутствующим в БД или пустой строкой
Dim mModeFlag As Boolean = True
If mMode Is Nothing OrElse IsDBNull(mMode) OrElse String.IsNullOrEmpty(mMode.ToString().Trim()) Then
mModeFlag = False
End If
'Если хотя бы один из параметров (nDigits или mMode) отсутствует, возвращается исходное число xValue
If (nDigitsFlag = False) Or (mModeFlag = False)
Return xValue
End If
If mMode = 1 Then
' Округление до n знаков после запятой
' В отличие от стандартной функции Math.Round(value, digits, MidpointRounding.AwayFromZero)
' может работать с отрицательными digits за счет сдвига
' Вычисление множителя
Dim factor As Double = Math.Pow(10, nDigits)
' Свдиг запятой на расстояние множителя, округление до целого, обратный сдвиг
' Направление сдвига зависит от знака (+-) в nDigits
Dim result As Double = Math.Round(xValue * factor, 0, MidpointRounding.AwayFromZero) / factor
' Форматирование результата (либо до целого(0), либо по положительному nDigits)
Return result.ToString("F" & Math.Max(0, nDigits))
End If
If mMode = 0 Then
' Округление до n значащих цифр   
' Определение порядка числа (до запятой)
Dim scale As Double = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(xValue))) + 1 - nDigits)
' Свдиг запятой влево (уменьшение порядка числа), округление, сдвиг вправо (увеличение порядка числа)
Dim result As Double = Math.Round(xValue / scale, 0, MidpointRounding.AwayFromZero) * scale
' Форматирование результата в компактную строку (удаление лишних нулей, научная нотация)
Return result.ToString("G")
End If
' При некорректном значении режима mMode
Return ""
End Function
</syntaxhighlight>


===Итоговый вариант на С#===
==Код функции==
<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);
/// <summary>
///     Режим округления.
/// </summary>
public enum RoundMode
{
     ToSignificantPlace = 0,
    ToDecimalPlace = 1
}
}
</syntaxhighlight>
</syntaxhighlight>

Текущая версия от 08:44, 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 цифр;
  • число масштабируется, округляется и возвращается в исходный порядок;
  • результат преобразуется в компактную строку (удаляются лишние нули в конце).

Использование в выражениях

Принципы использования:

Исходное значение Синтаксис в соответствии с формулой Результат
12345
[Rounding.RoundBase([DataBase.field], 2, 1)]
12345,00
12345.00
[Rounding.RoundBase([DataBase.field], 0, 1)]
12345
12345.01
[Rounding.RoundBase([DataBase.field], -2, 1)]
12300
555.55
[Rounding.RoundBase([DataBase.field], 1, 0)]
600

Примеры:

// A_2
[Rounding.RoundBase(ToDouble([Main.table_size]) / 1000, 0, 1)]

// R_3
[ResultOrDash(Rounding.RoundBase(First([Main.min_avg]), 2, 1))]

Использование во вкладке кода

// NG_2
string result = Rounding.RoundBase(normDouble, scaleInt, 1);

// NG_2
finalResult4 = Rounding.RoundBase(storage.Results[0], 2, 1);

// NG_2
return Rounding.RoundBase(firstNum, 2, 1) + " (" + Rounding.RoundBase(secondNum, 0, 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);
	}
}

/// <summary>
///     Режим округления.
/// </summary>
public enum RoundMode
{
    ToSignificantPlace = 0,
    ToDecimalPlace = 1
}