Будет ли десятичный или двойной работать лучше для переводов, которые должны быть точными до .00001? - PullRequest
4 голосов
/ 27 января 2010

Я инспектор в механическом цехе.У меня есть HTML-отчет, созданный другим инспектором, который имеет некоторые проблемы, которые мне нужно исправить.Это не первый раз: мне нужно что-то лучше, чем PowerShell и RegEx.(Не бойтесь интернет-воинов, я знаю, что я не должен использовать RegEx для html. Сейчас я использую HtmlAgilityPack.)

Я знаю, что существует множество подобных дискуссий по SO иИнтернет в целом.Я не нашел ничего такого особенного.Я могу написать несколько небольших экспериментальных приложений, чтобы протестировать некоторые из них (и я планирую), но я хочу иметь некоторое представление о том, будет ли это безопасно в будущем, прежде чем я реализую все это.Хотя я не программист по профессии, я хорошо понимаю концепции, о которых мы говорим;Не беспокойтесь о разговоре по моей голове.

При серии преобразований вероятно, что у меня будет ошибка больше, чем .0001?А как насчет .00001?
-Если выравнивание отчета отключено, возможно, мне потребуется несколько раз повернуть и перевести его.
-В настоящее время я реализовал только вращение и перевод, но я планирую добавить дополнительные преобразования.это может увеличить количество и сложность операций.
-Целочисленный компонент может исчисляться тысячами.
-Наши приборы сертифицированы по стандарту .0001.Применяются обычные правила значащих цифр для научных измерений.

Затраты на Decimal и написание функций триггера вручную будут невероятно трудоемкими (правка: во время выполнения)?
- Как правило, в отчете от 100 до 100точки.Каждая точка на самом деле представляет собой 2 точки: Nominal (как смоделировано) и Actual (как измерено.)
- проще всего проверить, но я хочу знать, прежде чем реализовывать математические функции для десятичного числа.

Сторонавопрос:
У меня есть класс точек, Point3D, который содержит x, y и z.Поскольку каждая точка данных состоит из двух (Nominal и Actual.), У меня есть класс MeasuredPoint с двумя экземплярами Point3D.Должно быть лучшее имя, чем MeasuredPoint, которое не должно раздражать долго.

О да, это C # /. Net.Спасибо,

Ответы [ 6 ]

5 голосов
/ 27 января 2010

Не реализуйте триггерные функции с десятичным! Существует причина, по которой стандартная библиотека их не предоставляет, а именно: если вы выполняете триггеринг, Decimal не предоставляет никаких дополнительных преимуществ.

Так как вы все равно будете работать в радианах, ваши значения определяются как кратные / отношения PI, которые не представлены ни в одной базовой системе. Принуждение представления к основанию десять скорее увеличится, чем уменьшится ошибка.

Если для вашего приложения важна точность (минимальная ошибка в ulps), вы должны прочитать Что должен знать каждый компьютерный специалист об арифметике с плавающей точкой от David Goldberg. Эта статья гораздо лучше объясняет, чем я.

В результате получается, что если желаемая точность составляет всего 5 десятичных разрядов, даже 32-разрядного числа с плавающей запятой (IEEE-754 одинарной точности) будет достаточно. 64-битная двойная точность IEEE-754 с двойной точностью поможет вам более точно определить погрешность, но 128-битное значение с плавающей точкой base-10 - это просто излишнее снижение производительности и почти наверняка не улучшит точность из ваших результатов одна йота.

3 голосов
/ 27 января 2010

Если вам нужна точность для нескольких операций, то вам действительно следует подумать об использовании десятичной дроби. Хотя это может быть приемлемым для хранения чисел в течение короткого времени, ни один формат с плавающей запятой, поддерживаемый IEEE754, не может сохранять свое значение в течение неопределенного времени, так как число применяемых операций увеличивается.

1 голос
/ 27 января 2010

Поскольку речь идет о поворотах, а также переводах, а также функциях тригонометрии, кажется безопасным предположить, что значения, о которых вы говорите, не являются точными , кратными 0,0001.

Исходя из этого предположения:

  • С десятичными числами вы будете по существу округлять до 0,0001 (или выбранной вами точности) после каждого шага, и эти ошибки округления будут накапливаться.

  • Двойные значения, как правило, будут более точными: вы будете хранить их со всей доступной точностью и округлять до четырех десятичных знаков при отображении результатов.

Например, в результате поворота или преобразования вы хотите переместиться на расстояние 1/3 (0,333 ....). И вы хотите повторить это движение три раза.

Если вы сохраните расстояния в десятичном виде с четырьмя десятичными знаками (0,3333), сумма составит 0,9999, ошибка 0,0001.

Если вы храните в двойном размере, вы можете достичь гораздо более высокой точности, и в качестве бонуса производительность будет лучше.

Действительно, десятичные дроби обычно используются только для финансовых расчетов, где результаты должны быть точно округлены до фиксированного числа десятичных знаков после запятой.

1 голос
/ 27 января 2010

Попробуйте найти библиотеку, которая бы отвечала вашим потребностям. Я наткнулся на W3b.sine в нерешительном поиске. Я определенно встречал других в прошлом.

0 голосов
/ 27 января 2010

Честно говоря, я думаю, что FLOAT был неправильным шагом в обработке данных. Поскольку люди работают в десятичном формате, а выходные данные всегда переводятся в десятичные, поплавок просто вызывает постоянные проблемы. Я использовал float, когда переменная может содержать широкий диапазон значений, например, в диапазоне от 1E-9 до 1E9, и использовать целые числа с фиксированным числом десятичных разрядов, управляемых в коде в противном случае. В наши дни с классом Java BigDecimal и схожей функциональностью в других языках почти нет причин использовать float. Возможно, в среде, где вы выполняете много вычислений и производительность является проблемой, вы бы приняли проблемы округления. Я не думаю, что использовал программу в программе как минимум десять лет.

0 голосов
/ 27 января 2010

Плавающие и двойные - быстрые приближения, вот и все.

Помимо 0.0 и 1.0, вы даже не получите точного представления для большинства констант (например, 0.1). Так что если вы должны гарантировать определенную точность, использование арифметики с плавающей запятой не вариант.

Но если цель состоит в том, чтобы достичь определенной точности, дать или взять немного, тогда удвоится. Просто следите за Потеря значимости .

...