visual sacar programacion porcentaje para iva descuento codigo calcular c# formatting

c# - sacar - ¿Cómo convertir la cadena de porcentaje para duplicar?



formula para sacar el porcentaje en c# (10)

Es sensible a la cultura, sustitúyelo así:

value = value.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");

Entonces analízalo.

Tengo una cadena como "1.5%" y quiero convertirla en valor doble.

Se puede hacer simple con lo siguiente:

public static double FromPercentageString(this string value) { return double.Parse(value.SubString(0, value.Length - 1)) / 100; }

pero no quiero usar este enfoque de análisis.

¿Hay algún otro enfoque con IFormatProvider o algo así?


Es una cadena, no importa lo que haga con ella para eliminar el signo% que aún tiene que analizarla a doble.


No estoy seguro de lo que es con todo este reemplazo de cadena, sustitución y convertidores.

Use la parte de la moneda de NumberFormat, pero rellénela con los formatos de porcentaje de su cultura requerida.

// input test value string value = (.015m).ToString("P", CultureInfo.CurrentCulture); // set up your format. double doubleTest; var numFormat = CultureInfo.CurrentCulture.NumberFormat; NumberFormatInfo nfi = new NumberFormatInfo() { CurrencyDecimalDigits = numFormat.PercentDecimalDigits, CurrencyDecimalSeparator = numFormat.PercentDecimalSeparator, CurrencyGroupSeparator = numFormat.PercentGroupSeparator, CurrencyGroupSizes = numFormat.PercentGroupSizes, CurrencyNegativePattern = numFormat.PercentNegativePattern, CurrencyPositivePattern = numFormat.PercentPositivePattern, CurrencySymbol = numFormat.PercentSymbol }; // load it. if (double.TryParse(value, NumberStyles.Currency, nfi, out doubleTest)) { doubleTest /= 100D; // use as required. }


Parece que muchas respuestas a esta pregunta implican reemplazar el símbolo de porcentaje de la cultura con la cadena vacía y luego analizar la cadena resultante como un valor numérico.

Tal vez me esté perdiendo algo, pero todavía hay algunos casos no manejados aquí. Específicamente, ¿qué sucede si PercentDecimalSeparator es diferente a NumberDecimalSeparator para la cultura actual? ¿Qué sucede si PercentGroupSeparator es diferente de NumberGroupSeparator para la cultura actual? ¿Qué sucede si PercentGroupSizes es diferente a NumberGroupSizes ?

Independientemente de si una cultura de este tipo existe prácticamente (si no es así, puede que surja una existencia en el futuro si se cambia el formato de una cultura), creo que se puede encontrar una mejor solución al problema si consideramos esto Adicional, casos especiales.

Aquí hay un fragmento de código que muestra una situación en la que las otras respuestas (basadas solo en reemplazar el símbolo de porcentaje) fallarán, y una sugerencia sobre cómo se podría hacer mejor de manera adecuada:

// Modify a culture so that it has different decimal separators and group separators for numbers and percentages. var customCulture = new CultureInfo("en-US") { NumberFormat = { PercentDecimalSeparator = "PDS", NumberDecimalSeparator = "NDS", PercentGroupSeparator = "PGS", NumberGroupSeparator = "NGS", PercentSymbol = "PS"} }; // Set the current thread''s culture to our custom culture Thread.CurrentThread.CurrentCulture = customCulture; // Create a percentage format string from a decimal value var percentStringCustomCulture = 123.45m.ToString("p"); Console.WriteLine(percentStringCustomCulture); // renders "12PGS345PDS00 PS" // Now just replace the percent symbol only, and try to parse as a numeric value (as suggested in the other answers) var deceptiveNumericStringInCustomCulture = percentStringCustomCulture.Replace(customCulture.NumberFormat.PercentSymbol, string.Empty); // THE FOLLOWING LINE THROWS A FORMATEXCEPTION var decimalParsedFromDeceptiveNumericStringInCustomCulture = decimal.Parse(deceptiveNumericStringInCustomCulture); // A better solution...replace the decimal separators and number group separators as well. var betterNumericStringInCustomCulture = deceptiveNumericStringInCustomCulture.Replace(customCulture.NumberFormat.PercentDecimalSeparator, customCulture.NumberFormat.NumberDecimalSeparator); // Here we mitigates issues potentially caused by group sizes by replacing the group separator by the empty string betterNumericStringInCustomCulture = betterNumericStringInCustomCulture.Replace(customCulture.NumberFormat.PercentGroupSeparator, string.Empty); // The following parse then yields the correct result var decimalParsedFromBetterNumericStringInCustomCulture = decimal.Parse(betterNumericStringInCustomCulture)/100m;

Sí, el código es un poco más largo, y tal vez estoy siendo pedante (es decir, tal vez esa cultura nunca exista). Dicho esto, me parece una solución más general. Espero que ayude a alguien :).



Reflexionando en .NET 4, aquí está la implementación de Microsoft (que se encuentra en System.Windows.Documents.ZoomPercentageConverter.ConvertBack). Puede modificar esto para satisfacer sus necesidades. Yo siempre uso la implementación de MS cuando sea posible!

try { string str = (string) value; if ((culture != null) && !string.IsNullOrEmpty(str)) { str = ((string) value).Trim(); if ((!culture.IsNeutralCulture && (str.Length > 0)) && (culture.NumberFormat != null)) { switch (culture.NumberFormat.PercentPositivePattern) { case 0: case 1: if ((str.Length - 1) == str.LastIndexOf(culture.NumberFormat.PercentSymbol, StringComparison.CurrentCultureIgnoreCase)) { str = str.Substring(0, str.Length - 1); } break; case 2: if (str.IndexOf(culture.NumberFormat.PercentSymbol, StringComparison.CurrentCultureIgnoreCase) == 0) { str = str.Substring(1); } break; } } num = Convert.ToDouble(str, culture); flag = true; } } catch (ArgumentOutOfRangeException) { } catch (ArgumentNullException) { } catch (FormatException) { } catch (OverflowException) { }


Si le importa capturar errores de formato, usaría TrimEnd en lugar de Reemplazar. Reemplazar permitiría que los errores de formato pasen sin ser detectados.

var num = decimal.Parse( value.TrimEnd( new char[] { ''%'', '' '' } ) ) / 100M;

Esto asegurará que el valor debe ser un número decimal seguido de cualquier número de espacios y signos de porcentaje, es decir, debe comenzar por lo menos con un valor en el formato adecuado. Para ser más precisos, es posible que desee dividir en ''%'', no eliminar las entradas vacías, luego asegúrese de que solo haya dos resultados y el segundo esté vacío. El primero debe ser el valor a convertir.

var pieces = value.Split( ''%'' ); if (pieces.Length > 2 || !string.IsNullOrEmpty(pieces[1])) { ... some error handling ... } var num = decimal.Parse( pieces[0] ) / 100M;

El uso de Reemplazar le permitirá realizar IMO con éxito e incorrectamente, analizar cosas como:

  • % 1.5
  • 1% .5
  • 1.% 5

en adición al 1.5%


Solo un poco mejor, pero menos propenso a errores:

public static double FromPercentageString(this string value) { return double.Parse(value.Replace("%","")) / 100; }


También puede combinar las dos respuestas principales para evitar aceptar valores no válidos mientras se mantiene flexible para diferentes culturas.

var num = double.Parse(value.TrimEnd(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol.ToCharArray() ) ) / 100d;


TypeConverter proporciona una forma unificada de convertir tipos de valores a otros tipos, así como para acceder a valores estándar y subpropiedades. http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverter%28VS.80%29.aspx

Esto es probablemente una exageración para las conversiones únicas. Es mucho más útil al vincular propiedades en ASP.NET o XAML, o al analizar archivos de configuración.

var result = new Percentage("1.5%"); double d = result.Value;

El porcentaje y su TypeConverter se definen como:

[TypeConverter(typeof(PercentageConverter))] public struct Percentage { public double Value; public Percentage( double value ) { Value = value; } public Percentage( string value ) { var pct = (Percentage) TypeDescriptor.GetConverter(GetType()).ConvertFromString(value); Value = pct.Value; } public override string ToString() { return ToString(CultureInfo.InvariantCulture); } public string ToString(CultureInfo Culture) { return TypeDescriptor.GetConverter(GetType()).ConvertToString(null, Culture, this); } } public class PercentageConverter : TypeConverter { static TypeConverter conv = TypeDescriptor.GetConverter(typeof(double)); public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return conv.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(Percentage)) { return true; } return conv.CanConvertTo(context, destinationType); } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { if (value == null) { return new Percentage(); } if (value is string) { string s = value as string; s = s.TrimEnd('' '', ''/t'', ''/r'', ''/n''); var percentage = s.EndsWith(culture.NumberFormat.PercentSymbol); if (percentage) { s = s.Substring(0, s.Length - culture.NumberFormat.PercentSymbol.Length); } double result = (double) conv.ConvertFromString(s); if (percentage) { result /= 100; } return new Percentage(result); } return new Percentage( (double) conv.ConvertFrom( context, culture, value )); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (!(value is Percentage)) { throw new ArgumentNullException("value"); } var pct = (Percentage) value; if (destinationType == typeof(string)) { return conv.ConvertTo( context, culture, pct.Value * 100, destinationType ) + culture.NumberFormat.PercentSymbol; } return conv.ConvertTo( context, culture, pct.Value, destinationType ); } }