2010-03-21 17 views
5

Cómo forzar doble x = 3/2; para devolver 1.5 en x sin el sufijo D o el casting? ¿Hay algún tipo de sobrecarga del operador que pueda hacerse? O alguna opción de compilador?Cómo forzar C# binary int division a devolver un doble?

Sorprendentemente, no es tan simple de añadir el casting o sufijo por la siguiente razón:

usuarios de negocios necesitan para escribir y depurar sus propias fórmulas. Actualmente, C# se está utilizando como un DSL (lenguaje específico de dominio) en el sentido de que estos usuarios no son ingenieros en informática. Entonces, todo lo que saben es cómo editar y crear algunos tipos de clases para mantener sus "reglas comerciales", que generalmente son solo fórmulas matemáticas.

Pero siempre asumen que el doble x = 3/2; devolverá x = 1.5 , sin embargo, en C# que devuelve 1.

A. Siempre olvidan esto, pierden el tiempo depurando, llámame para obtener asistencia técnica y lo solucionamos. B. piensan que es muy feo y perjudica la legibilidad de sus reglas comerciales.

Como ya sabe, las DSL deben ser más como un lenguaje natural.

Sí. Estamos planeando mudarnos a Boo y construir un DSL basado en él, pero eso es más adelante.

¿Existe una solución simple para hacer doble x = 3/2; ¿devuelve 1.5 por algo externo a la clase por lo que es invisible para los usuarios?

Gracias! Wayne

+7

C# no es un DSL. C# es un lenguaje de programación de propósito general utilizado para crear bibliotecas y aplicaciones. Si permite que los que no son programadores escriban e integren el código C# en su código base, entonces ya habrá perdido. Si necesita proporcionar soporte de scripting, inserte un motor de scripting en la aplicación. Si no tiene tiempo, cree una sintaxis o interfaz de usuario a escala reducida para propósitos especiales para compilar estas fórmulas matemáticas, de modo que pueda interpretarlas como prefiera en el código real. – Aaronaught

Respuesta

5

No, no hay ninguna solución que puede hacer 3/2 retorno 1.5.

La única solución teniendo en cuenta sus limitaciones es desalentar a los usuarios a utilizar literales en la fórmula. Anímalos a usar constantes. O, si realmente necesitan usar literales, aliéntelos a usar literales con un punto decimal.

+1

Bueno, a excepción de las soluciones que sí lo hacen. –

+0

@jdk, ¿me gusta? ... – Anzurio

+0

como solución http://stackoverflow.com/questions/2485881/how-to-force-c-binary-int-division-to-return-a-double/2485892#2485892 .. y como usted también mencionó literales pero probablemente comencé después de la primera oración o antes de que terminara. Así que no hay desacuerdo en el contexto después de todo. –

0

simple, si no me equivoco:

double x = 3D/2D; 
+0

El que pregunta dice: sin el sufijo D o fundición – Anzurio

0

Una solución sería escribir un método que haga esto por ellos y enseñarles a usarlo. Tu método siempre tomará dobles y la respuesta siempre tendrá la cantidad correcta de decimales.

0

No estoy bastante seguro, pero creo que se puede conseguir un doble, con 3.0/2.0 Pero si usted piensa 0,0 simplemente como otra forma de sufijación entonces no es la respuesta también :-)

+0

Esto es una suposición, no una respuesta. Responda las preguntas que están dentro de su experiencia. Las respuestas incorrectas hacen que sea más difícil encontrar consejos útiles. –

0

Tal vez puede probar RPN Expression Parser Class por ahora o bcParser? Estas son bibliotecas de análisis de expresiones muy pequeñas.

Me gustan los lenguajes fuertes y estáticos para mi propio trabajo, pero no creo que sean adecuados para principiantes que no tienen interés en convertirse en profesionales.

Así que tengo que decir que lamentablemente su elección de C# podría no haber sido la mejor para esa audiencia.

Boo parece estar tipicamente escrito a. ¿Has pensado en incorporar un motor Javascript, Python u otro motor de tipado dinámico? Por lo general, estos no son tan difíciles de conectar a una aplicación existente y usted tiene la ventaja de contar con una gran cantidad de documentación existente.

+0

Python antes de la versión 3.0 tiene el mismo problema con la división. – dan04

+0

Bueno, a todos los usuarios les gusta C# porque su primera prioridad es el rendimiento. Y el código de ruta crítica del sistema se escribió en un puntero inseguro, por lo que, según dicen, es el software más rápido en la industria comercial. Entonces aguantan C# por ahora hasta que podamos crear un DSL completo. – Wayne

+0

FYI, en cuanto a la elección del idioma, parece que Boo es la respuesta, ya que es extensible.Es decir, puede modificar cualquier cosa en el árbol del analizador en cualquier paso del proceso de compilación. Mi única preocupación es que las características del depurador sean muy importantes y que el autocode esté disponible con C#. Aún no estoy seguro de qué pasará con la capacidad de pasar el código para los usuarios de negocios si está en un lenguaje Boo modificado. – Wayne

0

¿Quizás un método de extensión en int32?

+0

ME ENCANTARÍA esto como una solución e investigaría específicamente e incluso lo probé. Pero aparentemente no se puede crear operador sobre cargadores como métodos de extensión según los autores del lenguaje C#. Si estoy equivocado, por favor corrígeme. – Wayne

0

Procesa las fórmulas antes de pasarlas al compilador C#. Haga algo como:

formula = Regex.Replace(formula, @"(^|[\^\s\+\*\/-])(\d+)(?![DF\.])", "$1$2D") 

Para convertir literales enteros a dobles literales.

De forma alternativa, puede usar una máquina de estado simple para rastrear si está o no en un literal de cadena o un comentario en lugar de reemplazar ciegamente, pero para fórmulas simples creo que una expresión regular será suficiente.

+0

Muy inteligente. Las "fórmulas" son realmente métodos completos con condicionales y submétodos. Es una lógica bastante compleja sobre las fórmulas. Específicamente, estas son reglas de comercio automatizadas. – Wayne

0

trata de hacerlo de esta manera:

double result = (double) 3/2; 

resultado = 1,5

1
Nunca

nunca se dicen ... El (doble) 3/2 solución se ve bien ...

pero falló para 4 + 5/6

prueba esto: donó al dominio público para ser utilizado libremente por SymbolicComputation.com.
Es alfa pero puede probarlo, solo lo he ejecutado en algunas pruebas, mi sitio y software deberían estar listos pronto. Utiliza Roslyn de Microsoft, pondrá una 'd' después de cada número si todo va bien. Roslyn también es alfa, pero analizará un poco de C#.

public static String AddDSuffixesToEquation(String inEquation) 
    { 
     SyntaxNode syntaxNode = EquationToSyntaxNode(inEquation); 
     List<SyntaxNode> branches = syntaxNode.DescendentNodesAndSelf().ToList(); 
     List<Int32> numericBranchIndexes = new List<int>(); 
     List<SyntaxNode> replacements = new List<SyntaxNode>(); 
     SyntaxNode replacement; 
     String lStr; 
     Int32 L; 
     for (L = 0; L < branches.Count; L++) 
     { 
      if (branches[L].Kind == SyntaxKind.NumericLiteralExpression) 
      { 
       numericBranchIndexes.Add(L); 
       lStr = branches[L].ToString() + "d"; 
       replacement = EquationToSyntaxNode(lStr); 
       replacements.Add(replacement); 
      } 
     } 

     replacement = EquationToSyntaxNode(inEquation); 
     List<SyntaxNode> replaceMeBranches; 
     for (L = numericBranchIndexes.Count - 1; L >= 0; L--) 
     { 
      replaceMeBranches = replacement.DescendentNodesAndSelf().ToList(); 
      replacement = replacement.ReplaceNode(replaceMeBranches[numericBranchIndexes[L]],replacements[L]); 
     } 
     return replacement.ToString(); 

    } 

    public static SyntaxNode EquationToSyntaxNode(String inEquation) 
    { 
     SyntaxTree tree = EquationToSyntaxTree(inEquation); 
     return EquationSyntaxTreeToEquationSyntaxNode(tree); 
    } 

    public static SyntaxTree EquationToSyntaxTree(String inEquation) 
    { 
     return SyntaxTree.ParseCompilationUnit("using System; class Calc { public static object Eval() { return " + inEquation + "; } }"); 
    } 

    public static SyntaxNode EquationSyntaxTreeToEquationSyntaxNode(SyntaxTree syntaxTree) 
    { 
     SyntaxNode syntaxNode = syntaxTree.Root.DescendentNodes().First(x => x.Kind == SyntaxKind.ReturnStatement); 
     return syntaxNode.ChildNodes().First(); 
    } 
Cuestiones relacionadas