Какая польза от принятия неточностей с плавающей запятой в С#

StackOverflow https://stackoverflow.com/questions/4603944

Вопрос

Я думал об этой проблеме последний немного дней, и я изо всех сил пытаюсь сформулировать свой вопрос.Тем не менее, я думаю, что я уловил то, что хотел знать.

Почему C# допускает неточность, используя плавающую точку для хранения данных?И в чем преимущество его использования перед другими методами?

Например, Math.Pow(Math.Sqrt(2),2) неточно в С#.Существуют языки программирования, которые позволяют его точно вычислить (например, Mathematica).

Один из аргументов, который я мог придумать, заключается в том, что точное вычисление происходит намного медленнее, чем просто борьба с неточностью, но Mathematica и Matlab используются для расчета гигантских научных задач, поэтому мне трудно поверить, что эти языки действительно значительно медленнее, чем C#.

Так почему же тогда?

ПС:Извините, что засыпаю вас такими вопросами, вы все мне очень помогли.

Это было полезно?

Решение

Почему C # принимает неточность, используя плавающие точки для хранения данных?

«C #» не принимает компромисс производительности над точностью; Пользователи делают или не принимают этого.

C # имеет три типа плавающих точек - поплавок, двойной и десятичной, потому что эти три типа соответствуют подавляющему большинству потребностей реальных программистов.

Float и Double хороши для «научных» расчетов, где ответ, который является правильным до трех или четырех десятичных знаков, всегда достаточно близко, потому что это точность, что исходное измерение пришло. Предположим, вы разделите 10,00 на 3 и получите 3.333333333333. Поскольку исходное измерение, вероятно, было точнее всего до 0,01, тот факт, что вычисленный результат отключен менее чем на 0,0000000000004, не имеет значения. В научных расчетах вы не представляете известные точные количества. Неточность в пятнадцатом десятином десятилетии не имеет значения, если первоначальное значение измерений было только точнее для второго десятичного времени.

Это, конечно, не верно для финансовых расчетов. Операнды к финансовому расчету обычно точны до двух десятичных знаков и представляют точные количества. Отказ Десятичная декорация хороша для «финансовых» расчетов, потому что результаты десятичных операций точный При условии, что все входы и выходы могут быть представлены точно так же, как десятичныелись (и все они в разумном диапазоне). Рабилисты все еще имеют ошибки округления, конечно, но операции, которые актуальны именно те, которые вы, вероятно, захотите быть точным при выполнении финансовых расчетов.

И какова польза от использования его над другими методами?

Вы должны указать, какие другие методы вы хотели бы сравнить против. Существует множество различных методик для выполнения расчетов на компьютерах.

Например, math.pow (math.sqrt (2), 2) не точна в C #. Есть языки программирования, которые могут рассчитать его точно (например, Mathematica).

Давайте быть понятным на этой точке; Mathematica не «рассчитывает» root 2 именно; Номер нерациональна, поэтому его нельзя рассчитать именно в любом конечном количестве хранения. Вместо этого, то, что делает Mathematica, это представляет числа в качестве объектов, которые описывают, как было выпущено число. Если вы говорите, «дайте мне квадратный корень из двух», то Mathematica по существу выделяет объект, который означает «применение оператора квадрата в точное число 2». Если вы тогда потратите это, у него есть логика специальной цели, которая говорит «Если вы что-то квадрат, что это был квадратный корень из чего-то еще, верните исходное значение». У Mathematica есть объекты, которые также представляют различные особые номера, такие как PI или E, и огромное количество правил для того, как различные манипуляции этих чисел объединяются вместе.

В основном это символический система; Это манипулирует числа так же, как люди делают, когда они делают карандаш и бумагу математики. Большинство компьютерных программ манипулируют номерами, такими как калькулятор: немедленно выполняют расчет и охватывают его. Если это не приемлемо, то вы должны придерживаться символической системы.

Один аргумент, о котором я мог бы подумать, это то, что вычислить его точно намного медленнее, а затем просто справиться с неточностью, но Mathematica & Matlab используются для расчета гигантских научных проблем, поэтому мне трудно поверить, что эти языки действительно значительно медленнее, чем C #.

Это не то, что они медленнее, хотя умножение плавающих точек действительно невероятно быстро быстро на современном оборудовании. Это то, что символический расчет двигатель Безмерно сложный комплекс. Отказ Это кодирует Все правила базовой математики, И есть много этих правил! C # не предназначен для профессионально-класса символического вычисления двигателя, он предназначен для общего назначения языка программирования.

Другие советы

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

Более того, ваш пример Matlab - подделка. MATLAB использует двойную точную плавающую точку арифметики как C #.

Почему C# допускает неточность, используя плавающую точку для хранения данных?

Таким образом, поддержка операций с плавающей запятой может соответствовать тому, как аппаратное обеспечение поддерживает плавающую запятую, то есть - это более или менее единственный способ воспользоваться преимуществами операций с плавающей запятой в аппаратном обеспечении, что много быстрее, чем программное решение.Недостаток заключается в том, что аппаратное обеспечение представляет числа с плавающей запятой с конечным числом бит, что приводит к неточности (обратите внимание, что неточность четко определена).

Другие способы представления значений с плавающей запятой требуют программного решения, они значительно медленнее и требуют больше места.«Любой» может реализовать это с помощью того, что доступно в С#, включая встроенную поддержку чисел с плавающей запятой для доступного оборудования, было бы довольно сложно для «любого», если бы это еще не поддерживалось в языке/CLR.

Для большинства проблем программирования неточность не проблема и float (или double) Типы данных достаточно хороши. Много лет назад не было такого понятия, как «значения с плавающей точкой», и программное обеспечение пришлось хранить такие значения как два целых числа. И производительность было Выпуск (не упоминание ошибок программирования - и сценариев WTF - от пользовательских функций расчета плавающих точек). Таким образом, Конвенция была разработана и вскоре после того, как компьютеры были оборудованы FPUс.

Теперь, когда использовать FPU для расчетов или использования других математических линейров / программ (таких как Mathematica), зависит от проблемы. Например, расчет вершин в трехмерной среде предпочитает производительность над точностью. Но бухгалтерское программное обеспечение отличается. В этом аспекте оба проблема отличаются; Бухгалтерское программное обеспечение не нужно будет рассчитать сложные числа миллионов раз в секундах :) (редактировать: или если это так, некоторые очень дорогие аппаратные средства, вероятно, будут частью уравнения тоже!)

если ты знать Что вы будете делать math.pow (math.sqrt (2), 2), то вы должны переосмыслить то, как вы храните оба значения (например, пересчитывая их каждый раз). Это не проблема с языком программирования, но более концептуальной проблемой.

C # и большинство всех других языков (кроме конкретных, таких как MATLAB) хранить числа плавающих точек в виде полей фиксированного размера (6 или 8 байтов), что приводит к неточности.

Одной из причин в том, что цифры и форматы числа являются однозначными и универсальными. Да, есть ошибки округления, но они постоянные и предсказуемые. Попытка настроить общий формат для любой алгоритмической задачи не тривиален.

Там немного объяснения здесь для математики

Краткая версия предназначена для обычного повседневного дневного плавающей точкой математики, оборудование может сделать это быстро с известным количеством неточной силы. Поэтому, если ваш расчет не полагается на точнее, то сделайте это быстрый путь.

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

Я не думаю, что это проблема C #. C # - это язык общего назначения и дает вам основные типы данных для игры. Если вы не довольны ними, вы всегда можете создавать свои собственные.

Кроме того, C # не тот, кто принимает неточность. Программист делает. Для большого набора проблем неточность приемлема. Поплавок не следует использовать, когда ожидается точный результат, но это решение для программиста не для дизайнера языка.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top