Как сохранить двухзначную точность

Я изо всех сил пытаюсь найти лучший способ сохранить двухзначную точность для десятичной переменной.

Здесь я разделил вопрос на 2 этапа:

Шаг 1. SQL-запрос

Чтобы получить 2-значную точность в SQL-запросе, я использую

CONVERT(DECIMAL(10,2), .....) // to get 2 digit precision

При выполнении я могу добиться двухзначной точности в своей SSMS.

NET_TOTAL  
---------    
10.00  
12.50  
14.25

Шаг 2. через код C#

Принимая во внимание, что в моем коде С#, когда я пытался сохранить значение в своем коде С#, он не сохранял двухзначную точность.

NET_TOTAL  
---------    
10       //lost my precision
12.5     //lost my precision
14.25

Ниже приведено мое объявление переменной.

public decimal? NET_TOTAL { get; set; } 

Но я чувствую обходной путь, используя свойства, но я не могу его получить.

я использую

  • dapper.net для операций с базой данных.
  • FileHelper.dll для преобразования списка запросов в файл CSV.

Хотелось бы узнать причину и способ решения этой проблемы.

Любая помощь горячо приветствуется.

Заранее спасибо.


person Praveen    schedule 01.08.2013    source источник
comment
Какой код вы выполняете, чтобы вернуть значения из базы данных?   -  person Steve    schedule 01.08.2013
comment
@ Стив Не уверен, что это то, о чем ты спрашиваешь. Для взаимодействия с базой данных я использую Dapper.NET (для преобразования результатов SQL в список С#). Запрос достаточно большой, поэтому я разместил соответствующую часть сценария sql.   -  person Praveen    schedule 01.08.2013
comment
Я спросил об этом, потому что у меня была аналогичная проблема с десятичными параметрами вывода dapper" title="использование десятичного числа с определенной точностью в качестве выходных параметров с помощью dapper"> stackoverflow.com/questions/17613635/   -  person Steve    schedule 01.08.2013


Ответы (4)


Нули в конце справа от десятичной дроби не являются точностью.
Это просто представление.

decimal d;
d = 10;
System.Diagnostics.Debug.WriteLine(string.Format("{0:N2}",d));
person paparazzo    schedule 01.08.2013
comment
Строго говоря, в .NET (но не в SQL Server) тип decimal действительно отслеживает точность отдельно; 2M и 2.00M в некоторых случаях могут иметь разные внутренние представления. - person Marc Gravell; 01.08.2013
comment
@MarcGravell Хорошо, согласен, что у них могут быть разные внутренние представления. Но 2M равно 2.00M, поэтому я бы считал их одинаковой точностью. Но может быть это то, о чем просит ОП, поскольку 2.00M пишет как 2.00 без форматирования. - person paparazzo; 02.08.2013

Ты можешь использовать

decimal.Round(value,decimalPoints);

Это вернет десятичное число, округленное до десятичных точек.

person Ishtiaq    schedule 01.08.2013

Вы путаете точность с представлением. В SSMS вы видите форматированное число (строку). То, что у вас есть в С# (и внутри БД), является «истинным» числом. В истинном обычно оканчивающемся 0 после запятой не включаются.

Если вы хотите отформатировать его, вы можете сделать что-то вроде NET_TOTAL.ToString("0.00")

Обратите внимание, что может быть другая проблема:

NET_TOTAL = 1.245;

decimal sum = NET_TOTAL + NET_TOTAL;

sum будет 2,29, но после обращения к БД NET_TOTAL будет 1,24 или 1,25 (в зависимости от того, как БД округлил 1,245), а пересчитанная сумма будет 2,28 или 2,3 .

person xanatos    schedule 01.08.2013
comment
О, значит, SSMS показывает это как строку? Но я использую CONVERT(DECIMAL(10,2), .....), чтобы получить его в виде двух цифр. - person Praveen; 01.08.2013
comment
@user1671639 user1671639 Если это на вашем экране, это строка :-) В памяти/БД число сохраняется не как 10.2, а как a двоичное представление этого числа (я использую a< /b>, поскольку существуют различные способы представления числа в памяти). - person xanatos; 01.08.2013
comment
Понятно. Судя по вашим обновлениям в ответе, NET_TOTAL = 1.245; decimal sum = NET_TOTAL + NET_TOTAL; я не буду выполнять никаких операций в коде C# (нет проблем :)). Поскольку это ETL, я не должен менять тип данных, есть ли какой-нибудь обходной путь, чтобы по-прежнему сохранять точность в 2 цифры? - person Praveen; 01.08.2013
comment
@user1671639 user1671639 У вас уже есть двухзначная точность, как я уже писал, вам нужно только отформатировать вывод (используя ToString или string.Format) - person xanatos; 01.08.2013

это приемлемо:

    private decimal? _netTotal;
    public decimal? NET_TOTAL{
        get{
            return _netTotal;
        }
        set
        {
            if (value.HasValue)
            {
                _netTotal = Math.Truncate(value.Value, 2); // or rounding
            }else{
                _netTotal = value;
            }
        }
    }

если вы хотите сохранить исходное значение, но представить его с двумя десятичными знаками, вы можете вместо этого изменить геттер: return Math.Truncate(value.Value, 2);

person Rex    schedule 01.08.2013
comment
Спасибо. Позвольте мне попробовать и вернуться к вам. - person Praveen; 01.08.2013
comment
это действительно зависит от того, где вы хотите иметь точность - если вы хотите просто иметь точность в какой-то форме выигрыша или на веб-странице, тогда отформатируйте ее на стороне графического интерфейса, если вы хотите иметь точность 2 десятичных знаков для расчета, тогда сделайте это как то, что я сказал. - person Rex; 01.08.2013