Может ли C# хранить более точные данные, чем double?

double в C# не обладают достаточной точностью для моих нужд. Я пишу фрактальную программу, и после того, как я несколько раз увеличил масштаб, я теряю точность.

Есть ли тип данных, который может содержать более точную информацию с плавающей запятой (т.е. больше десятичных знаков), чем двойной?


person simonalexander2005    schedule 29.03.2011    source источник
comment
Если вы хотите отобразить фракталы, масштабирование должно быть бесконечным. Возможно, вы захотите найти алгоритм, который возвращает ваши значения в зависимости от уровня масштабирования.   -  person Martin Hennings    schedule 29.03.2011


Ответы (3)


Да, decimal предназначен именно для этого.

Однако имейте в виду, что диапазон десятичного типа меньше, чем у двойного. То есть double может содержать большее значение, но при этом теряется точность. Или, как указано в MSDN:

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

Основное различие между decimal и double заключается в том, что decimal — это число с фиксированной точкой, а double — с плавающей запятой. Это означает, что decimal хранит точное значение, а double представляет значение, представленное дробью, и является менее точным. decimal составляет 128 бит, поэтому для хранения требуется двойное пространство. Вычисления на decimal тоже медленнее (мера!).

Если вам нужна еще большая точность, то BigInteger можно использовать из .NET 4. (Вам нужно будет самостоятельно обрабатывать десятичные точки). Здесь вы должны знать, что BigInteger неизменяем, поэтому любая арифметическая операция над ним создаст новый экземпляр - если числа большие, это может снизить производительность.

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

person driis    schedule 29.03.2011
comment
Целое, двойное, число с плавающей запятой, десятичное число тоже неизменяемы, а арифметические операции создают новые экземпляры... так что это отвлекающий маневр. Decimal и BigInteger работают медленно, потому что это не просто аппаратные примитивы. - person Mark Sowul; 08.04.2011
comment
Что ж, ладно, это не совсем отвлекающий маневр, потому что они могут становиться произвольно большими по сравнению с другими числовыми типами фиксированного размера, но если это так, то значение в любом случае не будет соответствовать другим типам. - person Mark Sowul; 08.04.2011
comment
Decimal — это тип с плавающей запятой, хотя его динамический диапазон меньше, чем у float. Я нахожу дизайн любопытным, учитывая, что тип занимает 16 байт, а тип с 68-битной частью целого числа и 60-битной дробью мог бы делать почти все, что Decimal делает более эффективно. Не такой большой диапазон на верхнем уровне и точность на нижнем уровне, но способный гарантировать, что сложение и вычитание будут выполняться с идеальной точностью или полностью потерпят неудачу - гарантия, не предоставляемая double. - person supercat; 17.09.2013

В .NET Framework 4 представлена ​​структура System.Numerics.BigInteger, которая может хранить числа с произвольно большой точностью.

person Dave Van den Eynde    schedule 29.03.2011
comment
Но имейте в виду, что выполнение арифметических операций над BigInteger может быть медленным. - person driis; 29.03.2011

Ознакомьтесь с BigInteger (.NET 4), если вам нужно даже больше точности, чем Decimal дает вам.

person Jonas Elfström    schedule 29.03.2011
comment
BigInteger (как и int) может хранить только целые числа. - person Adam Robinson; 29.03.2011
comment
Да, но часто довольно легко изменить фрактальные алгоритмы для работы с целыми числами или подделать BigInteger как десятичное число с фиксированной запятой. - person Jonas Elfström; 29.03.2011