Какой тип данных лучше всего использовать для денег в C #?
using System.ComponentModel.DataAnnotations; ... [DataType(DataType.Currency)] msdn.microsoft.com/en-us/library/…
Какой тип данных лучше всего использовать для денег в C #?
using System.ComponentModel.DataAnnotations; ... [DataType(DataType.Currency)] msdn.microsoft.com/en-us/library/…
Ответы:
Как это описано в десятичном виде как:
Ключевое слово decimal указывает на 128-битный тип данных. По сравнению с типами с плавающей точкой, десятичный тип имеет большую точность и меньший диапазон, что делает его подходящим для финансовых и денежных расчетов.
Вы можете использовать десятичное число следующим образом:
decimal myMoney = 300.5m;
Тип десятичного значения представляет десятичные числа в диапазоне от положительных 79,228,162,514,264,337,593,543,950,335 до отрицательных 79,228,162,514,264,337,593,543,950,335. Тип десятичного значения подходит для финансовых расчетов, требующих большого количества значащих целых и дробных цифр и без ошибок округления. Тип Decimal не устраняет необходимость округления. Скорее, это минимизирует ошибки из-за округления.
Я хотел бы указать на этот превосходный ответ от zneak о том, почему не следует использовать double.
Используйте шаблон Money из Patterns of Enterprise Application Architecture ; укажите сумму в десятичном виде и валюту в виде перечисления.
Moneynuget есть мертвая ссылка на github для сайта проекта, так что ... нет документов?
Десятичный. Если вы выбираете double, вы оставляете себя открытым для ошибок округления
doubleможет привести к ошибкам округления, потому что с плавающей точкой невозможно точно представить все числа (например, 0,01 не имеет точного представления в плавающей точке). Decimalс другой стороны, действительно представляет числа точно . (Компромисс Decimalимеет меньший диапазон, чем с плавающей запятой). Плавающая точка может дать вам * непреднамеренные * ошибки округления (например 0.01+0.01 != 0.02). Decimalможет дать вам ошибки округления, но только когда вы попросили об этом (например, Math.Round(0.01+0.02)возвращает ноль)
doubleи тщательно применяет масштабирование и округление, зависящее от предметной области, когда это уместно, оно может быть совершенно точным. Если кто-то неаккуратен в округлении, он decimalможет дать результаты, которые семантически неверны (например, если вы сложите несколько значений, которые должны быть округлены до ближайшей копейки, но на самом деле их сначала нет вокруг). Единственная хорошая вещь о decimalтом, что масштабирование встроено.
десятичная дробь имеет меньший диапазон, но большую точность - так что вы не потеряете все эти копейки со временем!
Полная информация здесь:
Согласитесь с шаблоном «Деньги»: работать с валютами слишком сложно, если вы используете десятичные дроби.
Если вы создаете класс Currency, вы можете поместить туда всю логику, связанную с деньгами, включая правильный метод ToString (), больший контроль над разбором значений и лучший контроль над делениями.
Кроме того, с классом Currency нет никакой возможности непреднамеренно смешать деньги с другими данными.
Другой вариант (особенно если вы катаетесь в своем собственном классе) - использовать int или int64 и обозначить четыре младшие цифры (или, возможно, даже 2) как «справа от десятичной точки». Так что «по краям» вам понадобится немного «* 10000» на входе и немного «/ 10000» на выходе. Это механизм хранения, используемый Microsoft SQL Server, см. Http://msdn.microsoft.com/en-au/library/ms179882.aspx.
Изюминка в том, что все ваше суммирование может быть выполнено с использованием (быстрой) целочисленной арифметики.
Большинство приложений, с которыми я работал, decimalпредставляют деньги. Это основано на предположении, что приложение никогда не будет связано с более чем одной валютой.
Это предположение может основываться на другом предположении, что приложение никогда не будет использоваться в других странах с разными валютами. Я видел случаи, когда это оказалось ложным.
Теперь это предположение оспаривается по-новому: новые валюты, такие как биткойн, становятся все более распространенными, и они не характерны для какой-либо страны. Вполне возможно, что приложение, используемое только в одной стране, может по-прежнему поддерживать несколько валют.
Некоторые люди скажут, что создание или даже использование типа только для денег - это «золотое покрытие» или добавление дополнительной сложности сверх известных требований. Я категорически не согласен. Чем более вездесуща концепция в вашей области, тем важнее приложить разумные усилия, чтобы использовать правильную абстракцию заранее. Если вы хотите увидеть сложность, попробуйте работать в приложении, которое раньше использовало, decimalи теперь Currencyрядом с каждым decimalсвойством есть дополнительное свойство.
Если вы используете неправильную абстракцию заранее, ее замена будет стоить больше работы. Это означает потенциальное внесение дефектов в существующий код, и, что самое приятное, эти дефекты, вероятно, будут связаны с денежными суммами, транзакциями с деньгами или просто с деньгами.
И это не так сложно использовать что-то кроме десятичной. Google "Nuget Money Type", и вы увидите, что многие разработчики создали такие абстракции (в том числе и я). Это легко. Это так же просто, как использовать DateTimeвместо сохранения даты в string.
Создайте свой собственный класс. Это кажется странным, но тип .Net не подходит для разных валют.