En tant que programmeur C et programmeur C #, l'une des choses que je n'aime pas dans C # est la façon dont les fonctions mathématiques sont verbeuses. Chaque fois que vous devez utiliser une fonction Sin, cosinus ou power par exemple, vous devez ajouter la classe statique Math. Cela conduit à un code très long lorsque l'équation elle-même est assez simple. Le problème devient encore pire si vous devez taper des types de données. En conséquence, à mon avis, la lisibilité en souffre. Par exemple:
double x = -Math.Cos(X) * Math.Sin(Z) + Math.Sin(X) * Math.Sin(Y) * Math.Cos(Z);
Par opposition à simplement
double x = -cos(X) * sin(Z) + sin(X) * sin(Y) * cos(Z);
C'est également le cas dans d'autres langages comme Java.
Je ne sais pas si cette question a réellement une solution, mais j'aimerais savoir s'il existe des astuces que les programmeurs C # ou Java utilisent pour améliorer la lisibilité du code Math. Je me rends compte cependant que C # / Java / etc. ne sont pas des langages orientés mathématiques comme MATLAB ou similaire, donc cela a du sens. Mais parfois, il faudrait encore écrire du code mathématique et ce serait bien si on pouvait le rendre plus lisible.
la source
using System.Math; … double x = -Cos(X) * Sin(Z) + Sin(X) * Sin(Y) * Cos(Z);
.Réponses:
Vous pouvez définir des fonctions locales qui appellent les fonctions statiques globales. Espérons que le compilateur alignera les wrappers, puis le compilateur JIT produira un code d'assemblage serré pour les opérations réelles. Par exemple:
Vous pouvez également créer des fonctions qui regroupent des opérations mathématiques courantes en opérations simples. Cela minimiserait le nombre d'instances où des fonctions comme
sin
etcos
apparaissent dans votre code, rendant ainsi la maladresse d'invoquer les fonctions statiques globales moins perceptible. Par exemple:Vous travaillez au niveau des points et des rotations, et les fonctions trigonométriques sous-jacentes sont enterrées.
la source
En Java, il existe de nombreux outils pour rendre certaines choses moins verbeuses, il suffit d'en être conscient. Celui qui est utile dans ce cas est celui de l'
static
import ( page tutoriel , wikipedia ).Dans ce cas,
fonctionne très bien ( ideone ). C'est un peu lourd de faire une importation statique de toute la classe Math, mais si vous faites beaucoup de mathématiques, alors cela pourrait être nécessaire.
L'importation statique vous permet d'importer un champ ou une méthode statique dans l'espace de noms de cette classe et de l'appeler sans exiger le nom du package. Vous le trouverez souvent dans les cas de test Junit où l'
import static org.junit.Assert.*;
on trouve tous les assertions disponibles.la source
public interface Constants { final static public double PI = 3.14; }
et puispublic class Foo implements Constants
dans toutes les classes pour avoir accès aux constantes de l'interface. Cela a fait un gros gâchis. Ainsi, avec 1.5, l'importation statique a été ajoutée pour permettre d'extraire des constantes et des fonctions statiques spécifiques sans avoir à implémenter une interface.import static java.lang.Math.cos;
Avec C # 6.0, vous pouvez utiliser la fonction d'importation statique.
Votre code pourrait être:
Voir: Static Using Statements (AC # 6.0 Language Preview)
EDIT: depuis Visual Studio 2015, CTP sorti en janvier 2015, l'importation statique nécessite un mot clé explicite
static
. comme:la source
En plus des autres bonnes réponses ici, je pourrais également recommander une DSL pour les situations avec une complexité mathématique substantielle (pas des cas d'utilisation moyens, mais peut-être certains projets financiers ou académiques).
Avec un outil de génération DSL tel que Xtext , vous pourriez définir votre propre grammaire mathématique simplifiée, qui pourrait à son tour générer une classe contenant la représentation Java (ou tout autre langage) de vos formules.
Expression DSL:
Sortie générée:
Dans un exemple aussi simple, les avantages de la création de la grammaire et du plug-in Eclipse ne seraient pas utiles, mais pour des projets plus complexes, cela pourrait générer de grands avantages, surtout si la DSL permettait aux gens d'affaires ou aux chercheurs universitaires de conserver des documents formels dans un cadre confortable. et soyez assuré que leur travail a été traduit avec précision dans la langue de mise en œuvre du projet.
la source
En C #, vous pouvez utiliser des méthodes d'extension.
Ce qui suit se lit assez bien une fois que vous vous êtes habitué à la notation "postfix":
Malheureusement, la priorité des opérateurs rend les choses un peu plus laides lorsqu'il s'agit de nombres négatifs ici. Si vous voulez calculer
Math.Cos(-X)
au lieu de-Math.Cos(X)
vous devrez mettre le nombre entre parenthèses:la source
x.Sin()
prendrait un certain ajustement, mais j'abuse des méthodes d'extension et ce serait, personnellement, ma première inclination.C #: Une variante de la réponse de Randall Cook , que j'aime parce qu'elle conserve plus l'aspect mathématique du code que les méthodes d'extension, consiste à utiliser un wrapper mais à utiliser des références de fonction pour les appels plutôt que de les envelopper. Personnellement, je pense que cela rend le code plus propre, mais il fait essentiellement la même chose.
J'ai créé un petit programme de test LINQPad comprenant les fonctions encapsulées de Randall, mes références de fonction et les appels directs.
La fonction des appels référencés prend essentiellement le même temps que les appels directs. Les fonctions encapsulées sont toujours plus lentes - mais pas énormément.
Voici le code:
Résultats:
la source
Utilisez Scala! Vous pouvez définir des opérateurs symboliques et vous n'avez pas besoin de parens pour vos méthodes. Cela rend les mathématiques façon plus facile à interpréter.
Par exemple, le même calcul dans Scala et Java pourrait être quelque chose comme:
Cela s'additionne assez rapidement.
la source