Преобразование текстовой части в десятичную
Похоже на этот вопрос только на С# вместо JavaScript. Я не мог найти ничего для С# при поиске
У меня есть текстовое поле, которое будет принимать количество, которое позже будет храниться как double в базе данных. Однако возможно, что некоторые количества будут введены в виде струнных фракций, например 1/2 для 0,5.
Я хочу, чтобы иметь возможность конвертировать их в десятичные числа, прежде чем хранить их в базе данных (возможность конвертировать назад было бы неплохо, но не обязательно). Я хочу иметь возможность обрабатывать как фракции, так и смешанные числа, например. 2 1/2 сохраняется как 2,5
Кто-нибудь знает способ сделать это?
Ответы
Ответ 1
Попробуйте разбить его на пробел и слэш, например:
double FractionToDouble(string fraction) {
double result;
if(double.TryParse(fraction, out result)) {
return result;
}
string[] split = fraction.Split(new char[] { ' ', '/' });
if(split.Length == 2 || split.Length == 3) {
int a, b;
if(int.TryParse(split[0], out a) && int.TryParse(split[1], out b)) {
if(split.Length == 2) {
return (double)a / b;
}
int c;
if(int.TryParse(split[2], out c)) {
return a + (double)b / c;
}
}
}
throw new FormatException("Not a valid fraction.");
}
Эй, это сработало! Не забудьте также проверить деление на ноль. В результате вы получите Infinity, -Infinity или NaN.
Ответ 2
И вот еще одно решение, но с чуть более бесшовной интеграцией:
public class FractionalNumber
{
public Double Result
{
get { return this.result; }
private set { this.result = value; }
}
private Double result;
public FractionalNumber(String input)
{
this.Result = this.Parse(input);
}
private Double Parse(String input)
{
input = (input ?? String.Empty).Trim();
if (String.IsNullOrEmpty(input))
{
throw new ArgumentNullException("input");
}
// standard decimal number (e.g. 1.125)
if (input.IndexOf('.') != -1 || (input.IndexOf(' ') == -1 && input.IndexOf('/') == -1 && input.IndexOf('\\') == -1))
{
Double result;
if (Double.TryParse(input, out result))
{
return result;
}
}
String[] parts = input.Split(new[] { ' ', '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
// stand-off fractional (e.g. 7/8)
if (input.IndexOf(' ') == -1 && parts.Length == 2)
{
Double num, den;
if (Double.TryParse(parts[0], out num) && Double.TryParse(parts[1], out den))
{
return num / den;
}
}
// Number and fraction (e.g. 2 1/2)
if (parts.Length == 3)
{
Double whole, num, den;
if (Double.TryParse(parts[0], out whole) && Double.TryParse(parts[1], out num) && Double.TryParse(parts[2], out den))
{
return whole + (num / den);
}
}
// Bogus / unable to parse
return Double.NaN;
}
public override string ToString()
{
return this.Result.ToString();
}
public static implicit operator Double(FractionalNumber number)
{
return number.Result;
}
}
И поскольку он реализует неявный оператор, его можно использовать просто:
Double number = new FractionalNumber("3 1/2");
Все, что не может быть проанализировано, возвращает двойную константу Double.NaN
. Не входя в список возможных входов, это работало с некоторыми основами. Не стесняйтесь настраивать класс в соответствии с вашими потребностями.
Ответ 3
Разделите строку на "/", затем разделите два числа.
public float FractionToDecimal(String input)
{
String[] fraction = input.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
if (fraction.Length != 2)
{
throw new ArgumentOutOfRangeException();
}
Int32 numerator, denominator;
if (Int32.TryParse(fraction[0], out numerator) && Int32.TryParse(fraction[1], out denominator))
{
if (denominator == 0)
{
throw new InvalidOperationException("Divide by 0 occurred");
}
return (float)numerator / denominator;
}
throw new ArgumentException();
}
Ответ 4
Вы можете попробовать что-то вроде этого: http://csharpeval.codeplex.com/ или это: https://github.com/Giorgi/Math-Expression-Evaluator
Обе библиотеки представляют собой полные математические выражения, написанные на С#. Они, вероятно, слишком переполнены для вашего случая использования, но стоит упомянуть в пользу других.
Ответ 5
decimal re = (decimal)1/7;
работает для меня.