Как программист C и программист C #, одна вещь, которая мне не нравится в C #, - это подробные математические функции. Например, каждый раз, когда вам нужно будет использовать функцию Sin, cosine или power, вы должны будете добавить статический класс Math. Это приводит к очень длинному коду, когда само уравнение довольно простое. Проблема становится еще хуже, если вам нужно типизировать типы данных. В результате, на мой взгляд, читаемость страдает. Например:
double x = -Math.Cos(X) * Math.Sin(Z) + Math.Sin(X) * Math.Sin(Y) * Math.Cos(Z);
В отличие от просто
double x = -cos(X) * sin(Z) + sin(X) * sin(Y) * cos(Z);
Это также имеет место в других языках, таких как Java.
Я не уверен, что этот вопрос действительно имеет решение, но я хотел бы знать, есть ли какие-нибудь хитрости, которые используют программисты на C # или Java для улучшения читаемости кода Math. Однако я понимаю, что C # / Java / и т. Д. не ориентированные на математику языки, такие как MATLAB или подобные, так что это имеет смысл. Но иногда нужно было бы написать математический код, и было бы здорово, если бы он мог сделать его более читабельным.
источник
using System.Math; … double x = -Cos(X) * Sin(Z) + Sin(X) * Sin(Y) * Cos(Z);
.Ответы:
Вы можете определить локальные функции, которые вызывают глобальные статические функции. Надеемся, что компилятор встроит оболочки, а затем JIT-компилятор создаст жесткий ассемблерный код для реальных операций. Например:
Вы также можете создавать функции, которые объединяют общие математические операции в отдельные операции. Это сведет к минимуму количество случаев, когда функции похожи
sin
иcos
появляются в вашем коде, тем самым делая неловкость вызова глобальных статических функций менее заметной. Например:Вы работаете на уровне точек и поворотов, и основные функции триггера скрыты.
источник
В Java есть много инструментов, позволяющих сделать некоторые вещи менее многословными, вы просто должны знать о них. В этом случае полезен
static
импорт ( страница учебника , википедия ).В таком случае,
работает довольно красиво ( ideone ). Немного тяжело выполнять статический импорт всех классов Math, но если вы много занимаетесь математикой, то это может потребоваться.
Статический импорт позволяет импортировать статическое поле или метод в пространство имен этого класса и вызывать его без указания имени пакета. Вы часто это в тех случаях , тест JUnit , где
import static org.junit.Assert.*;
находится , чтобы получить все утверждает доступны.источник
public interface Constants { final static public double PI = 3.14; }
а затемpublic class Foo implements Constants
во всех классах, чтобы получить доступ к константам в интерфейсе. Это сделало большой беспорядок. Итак, в версии 1.5 был добавлен статический импорт, позволяющий использовать определенные константы и статические функции без необходимости реализации интерфейса.import static java.lang.Math.cos;
С C # 6.0 вы можете использовать функцию статического импорта.
Ваш код может быть:
См. Статическое использование операторов (AC # 6.0 Language Preview)
РЕДАКТИРОВАТЬ: Начиная с Visual Studio 2015, CTP выпущен в январе 2015 года, статический импорт требует явного ключевого слова
static
. нравиться:источник
В дополнение к другим хорошим ответам здесь, я мог бы также рекомендовать DSL для ситуаций с существенной математической сложностью (не средние варианты использования, но, возможно, некоторые финансовые или академические проекты).
С помощью инструмента создания DSL, такого как Xtext , вы можете определить свою собственную упрощенную математическую грамматику, которая, в свою очередь, может сгенерировать класс, содержащий представление ваших формул на Java (или любом другом языке).
DSL Expression:
Сгенерированный выход:
В таком простом примере преимущества создания грамматики и плагина Eclipse не были бы полезны, но для более сложных проектов это могло бы принести большие выгоды, особенно если DSL позволил деловым людям или академическим исследователям поддерживать формальные документы в удобной форме. язык, и будьте уверены, что их работа была точно переведена на язык реализации проекта.
источник
В C # вы можете использовать методы расширения.
Ниже вы можете прочитать довольно хорошо, как только вы привыкнете к записи «postfix»:
К сожалению, при работе с отрицательными числами приоритеты операторов немного усложняют ситуацию. Если вы хотите рассчитать
Math.Cos(-X)
вместо-Math.Cos(X)
вас нужно будет заключить число в круглые скобки:источник
x.Sin()
потребовалась бы некоторая корректировка, но я злоупотребляю методами расширения, и это будет, лично я, моим первым желанием.C #: Вариант ответа Рэндалла Кука , который мне нравится, потому что он поддерживает математический «вид» кода больше, чем методы расширения, состоит в том, чтобы использовать оболочку, но использовать ссылки на функции для вызовов, а не заключать их в оболочку. Я лично думаю, что это делает код более чистым, но в основном делает то же самое.
Я запустил небольшую тестовую программу LINQPad, включающую упакованные функции Рэндалла, ссылки на мои функции и прямые вызовы.
Вызовы, на которые ссылаются функции, в основном занимают то же время, что и прямые вызовы. Обернутые функции постоянно работают медленнее, хотя и не очень сильно.
Вот код:
Результаты:
источник
Используйте Scala! Вы можете определять символические операторы, и вам не нужны парены для ваших методов. Это делает математику так легче интерпретировать.
Например, один и тот же расчет в Scala и Java может выглядеть примерно так:
Это складывается довольно быстро.
источник