2009-04-03 3 views
2
  1. В «F# for Scientists» говорит Джон Harrop:точности плавающей запятой в F # (и .NET)

    Грубо говоря, значения типа междунар приближенные реальные числа от мин-ИНТ и макс-междунар с постоянная абсолютная погрешность + - 1/2 , тогда как значения типа float имеют приблизительно постоянную относительную погрешность, которая равна - это крошечная доля процента.

    Теперь, что это значит? Тип Int является неточным?

  2. Почему C# для (1 - 0.9) возвращает 0,1, но F # возвращает 0.099999999999978? Является ли C# более точным и подходит для научных расчетов?

  3. Должны ли мы использовать десятичные значения вместо double/float для научных вычислений?

ответ

6
  1. Для произвольного действительного числа либо целочисленный тип, либо тип с плавающей запятой будет обеспечивать приближение. Интегральное приближение никогда не будет выключено более чем на 0,5 в одном или другом направлении (при условии, что действительное число соответствует диапазону этого интегрального типа). Сближение с плавающей запятой никогда не будет отключено более чем небольшим процентом (опять же, если предположить, что реальный находится в пределах диапазона значений, поддерживаемых этим типом с плавающей точкой).Это означает, что при меньших значениях типы с плавающей точкой будут обеспечивать более близкие приближения (например, сохранение аппроксимации PI в поплавке будет намного более точным, чем int-приближение 3). Однако при очень больших значениях аппроксимация интегрального типа будет фактически лучше, чем тип с плавающей запятой (например, рассмотрим значение 9223372036854775806.7, которое только на 0,3, если оно представлено как 9223372036854775807 как длинное, но которое представлено 9223372036854780000.000000 при сохранении как поплавок).

  2. Это всего лишь артефакт того, как вы печатаете значения. 9/10 и 1/10 не могут быть точно представлены как значения с плавающей запятой (поскольку знаменатель не является степенью двух), так же как 1/3 не может быть точно записано как десятичное (вы получаете 0,333 ... где повторение 3 навсегда). Независимо от используемого языка .NET, внутреннее представление этого значения будет одинаковым, но разные способы печати значения могут отображаться по-разному. Обратите внимание: если вы оцениваете 1.0 - 0.9 в FSI, результат отображается как 0,1 (по крайней мере, на моем компьютере).

  3. Какой тип, который вы используете в научных расчетах, будет зависеть именно от того, чего вы пытаетесь достичь. Ваш ответ, как правило, будет примерно точным. Насколько он вам нужен? Каковы ваши требования к производительности? Я считаю, что десятичный тип на самом деле является числом с фиксированной точкой, что может сделать его неприемлемым для расчетов с очень маленькими или очень большими значениями. Заметим также, что F # включает произвольные прецизионные рациональные числа (с типом BigNum), которые также могут быть подходящими в зависимости от вашего ввода.

2

Нет, F # и C# использует тот же двойной тип. Плавающая точка почти всегда неточна. Однако целые числа являются точными.

UPDATE:

Причина, почему вы видите разницу из-за печати числа, а не фактического представления.

2

В первом пункте я бы сказал, что int может использоваться для представления любого действительного числа в диапазоне intger с постоянной максимальной ошибкой в ​​[-0,5, 0.5]. Это имеет смысл. Например, pi может быть представлено целым числом 3 с ошибкой, меньшей 0,15.

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

0

3 - Это зависит от расчетов: иногда плавать - хороший выбор, иногда вы можете использовать int. Но есть задачи, когда вам не хватает точности для любого числа с плавающей запятой и десятичной.

Причина против использования Int:

> 1/2;; 
val it : int = 0 

Причина против использования поплавка (также известного как двойные в C#):

> (1E-10 + 1E+10) - 1E+10;; 
val it : float = 0.0 

Причины против BCL десятичного:

> decimal 1E-100;; 
val it : decimal = 0M 

У каждого перечисленного типа есть свои недостатки.

+0

MSDN заявляет, что это System.Double: http://msdn.microsoft.com/en-us/library/ee353546.aspx – vpolozov

Смежные вопросы