C # ошибка поплавка? 0,1 - 0,1 = 1,490116E-08 - PullRequest
0 голосов
/ 26 января 2009

Что происходит ?! Вычитание работает нормально, пока я не доберусь до 0,1 - 0,1. Я в Visual C # 2008 с использованием API nonoba.com.

Console.WriteLine("hit! " + Users[targetNum].character.health + " : " + player.character.profile.attackPower);

Users[targetNum].character.health -= player.character.profile.attackPower;

Console.WriteLine("health! " + Users[targetNum].character.health);

выход:

hit! 0.1 : 0.1
health! 1.490116E-08

Спасибо всем - я мог бы использовать десятичный тип, так как я обычно добавляю / вычитаю красивые круглые числа. А пока я просто пойду с:

if (Users[targetNum].character.health <= 0.00001)

Между прочим, я знал, что это на самом деле не будет "ошибкой" в c # - я думал, что это будет либо из-за ошибки в моем коде, либо из-за нехватки понимания.

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

Ответы [ 5 ]

17 голосов
/ 26 января 2009

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

По сути, если вы не уверены, что это точно один и тот же 0,1 в обоих случаях (то есть с ними ничего не сделано), вы вряд ли получите ноль; в общем, вы получите что-то очень близко к нулю. С decimal вы обычно получаете больше, чем ожидаете, интуитивно.

Смотрите также страницы Джона Скита здесь:

12 голосов
/ 26 января 2009

Вам, очевидно, нужно прочитать «Что должен знать каждый учёный о числах с плавающей запятой» .

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

1 голос
/ 26 января 2009

Если вы всегда складываете и вычитаете «хорошие круглые» числа, которые составляют десятые или сотые доли, то вы можете отслеживать свои значения попаданий и здоровья в целых десятых долях единиц. Аналогия - финансовая программа, которая отслеживает деньги в целочисленных центах вместо долларов с плавающей запятой. Использование целых чисел позволяет избежать всех проблем математики с плавающей запятой.

0 голосов
/ 08 ноября 2009

Немного оффтоп, но вот интересное чтение, которое описывает, почему cos(x) != cos(y) может быть правдой, даже если x == y:

http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18

0 голосов
/ 26 января 2009

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

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