Análisis numérico en coma flotante: ¿Existe un algoritmo Catch All?


Una de las partes divertidas de la programación multicultural son los formatos numéricos.

  • Los estadounidenses usan 10,000. 50
  • Los alemanes usan 10.000, 50
  • Uso francés 10 000,50

Mi primer enfoque sería tomar la cadena, analizarla hacia atrás, hasta que encuentre un separador y lo use como mi separador decimal. Hay un defecto obvio en eso: 10.000 se interpretaría como 10.

Otro enfoque: si la cadena contiene 2 caracteres no numéricos diferentes, use el último como separador decimal y descartar los demás. Si solo tengo uno, verifique si ocurre más de una vez y descárguelo si lo hace. Si solo aparece una vez, compruebe si tiene 3 dígitos después de él. En caso afirmativo, deséchelo, de lo contrario úselo como separador decimal.

La "mejor solución" obvia sería detectar la cultura o el Navegador del Usuario, pero eso no funciona si tiene un francés que usa un Navegador Windows/en-US.

¿El. net Framework contiene alguna magia negra mítica analizador de coma flotante que es mejor que Double.(Try)Parse() al intentar detectar automáticamente el formato del número?

Author: mattytommo, 2008-08-01

4 answers

Creo que lo mejor que puedes hacer en este caso es tomar sus comentarios y luego mostrarles lo que crees que significan. Si no están de acuerdo, muéstrales el formato que esperas y haz que lo introduzcan de nuevo.

 27
Author: Ryan Fox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-01 23:17:53

No conozco el ASP.NET lado del problema, pero. NET tiene una clase bastante poderosa: System.Globalización.CultureInfo . Puede usar el siguiente código para analizar una cadena que contenga un valor doble:

double d = double.Parse("100.20", CultureInfo.CurrentCulture);
//  -- OR --
double d = double.Parse("100.20", CultureInfo.CurrentUICulture);

Si ASP.NET de alguna manera (es decir, usando encabezados de solicitud HTTP) pasa el CultureInfo del usuario actual a cualquiera de los dos CultureInfo.CurrentCulture o CultureInfo.La cultura actual, estos funcionarán bien.

 27
Author: huseyint,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-01 20:02:08

No puedes complacer a todos. Si entro diez como 10.000, y alguien entra diez mil como 10.000, no puedes manejar eso sin algún conocimiento de la cultura de la entrada. Detectar la cultura de alguna manera (navegador, configuración del sistema - ¿cuál es el caso de uso? ¿ASP? Aplicación interna, o abierta al mundo?), o proporcionar un ejemplo del formato esperado, y utilizar el analizador más indulgente que pueda. Probablemente algo como:

double d = Double.Parse("5,000.00", NumberStyles.Any, CultureInfo.InvariantCulture);
 12
Author: Chris Marasti-Georg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-01 20:05:12

La diferencia entre 12.345 en francés e inglés es un factor de 1000. Si proporciona un rango esperado donde max

Tomemos, por ejemplo, la altura de una persona (incluidos bebés y niños) en mm.

Al usar un rango de 200-3000, una entrada de 1.800 o 1.800 puede interpretarse sin ambigüedad como 1 metro y 80 centímetros, mientras que una entrada de 912.300 o 912.300 puede interpretarse sin ambigüedad como 91 centímetros y 2.3 milímetros.

 10
Author: Michiel de Mare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-02 12:28:12