2009-05-16 1 views
0

У меня есть код, и я его не понимаю. Я разрабатываю приложение, точность которого очень важна. но это не важно для .NET, почему? Я не знаю.Двойная точность

double value = 3.5; 
MessageBox.Show((value + 1 * Math.Pow(10, -20)).ToString()); 

но окно сообщений показывает: 3,5 Пожалуйста, помогите мне, спасибо.

+0

http://stackoverflow.com/questions/566958/double-precision-problems-on-c-net –

+0

Не существует значения 'double', которое равно 3,50000000000000000001. Самый близкий к этому номеру - 3,5. –

ответ

1

У вас может быть точность, но это зависит от того, что еще вы хотите сделать. Если вы поместите в консольном приложении:

double a = 1e-20; 
Console.WriteLine(" a = {0}", a); 
Console.WriteLine("1+a = {0}", 1+a); 

decimal b = 1e-20M; 
Console.WriteLine(" b = {0}", b); 
Console.WriteLine("1+b = {0}", 1+b); 

Вы получите

a = 1E-20 
1+a = 1 
b = 0,00000000000000000001 
1+b = 1,00000000000000000001 

Но обратите внимание, что Pow функции, как и почти все в классе Math, только принимает двойники:

double Pow(double x, double y); 

Таким образом, вы не можете взять синус десятичной дроби (иначе, переведя его в двойное)

Также см. this question.

1

Или используйте тип Decimal, а не двойной.

+0

Но вы не можете использовать Math.Pow() по десятичным знакам –

+1

10^-20 можно легко указать как константу. Нет необходимости ссылаться на Math.Pow() здесь. – Joey

+0

Да, вы правы, но я просто хотел показать свою проблему. –

2

Точность Double составляет 15 цифр (17 цифр внутри). Значение, которое вы вычисляете с помощью Math.Pow, верное, но когда вы добавляете его в value, он слишком мал, чтобы изменить ситуацию.

Редактировать:
Десятичное число может обрабатывать эту точность, но не вычислять. Если вы хотите, что точность, необходимо сделать расчет, а затем преобразовать каждое значение в Decimal перед добавлением их вместе:

double value = 3.5; 
double small = Math.Pow(10, -20); 

Decimal result = (Decimal)value + (Decimal)small; 

MessageBox.Show(result.ToString()); 
+0

, но что мне делать с этим номером? –

+0

Десятичная имеет такую ​​точность, но вам нужно сделать вычисление как двойное, а затем преобразовать их в десятичный, прежде чем добавлять их. См. Мое редактирование выше. – Guffa

0

двойной точности означает, что он может содержать 15-16 цифр. 3,5 + 1е-20 = 21 цифра. Он не может быть представлен двойным образом. Вы можете использовать другой тип, например десятичный.

+0

, но сколько чисел я могу получить после с плавающей запятой? –

+0

15-16 цифр всего. С плавающей запятой может быть где угодно до, после или в промежутке между этими цифрами – Kcats

2

Если вы делаете что-либо там, где точность очень важна, вам нужно знать ограничения плавающей запятой. Хорошая ссылка David Goldberg's "What Every Computer Scientist Should Know About Floating-Point Arithmetic".

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

+0

Хорошая статья, но для не-математиков немного читать. Это немного легче читать для кодовых обезьян: http://floating-point-gui.de/ –