2013-12-12 4 views
0

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

long a = (long)((720000 + 144000) * 0.285); 

Фактическое значение: 246.239

Ожидаемое значение а: 246.240

Изменение типа «а» удвоить и удаление результатов преобразования в правильное значение , но я пишу программу, которая может привести к очень большим числам - неправильно ли я использовать длинный тип?

Любые советы приветствуются!

+0

Обязательно: "Что каждый программист должен знать о плавающей точкой" http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – James

+0

Попробуйте 'BigInteger а = новый BigInteger (((720000 + 144000) * 285))/1000; ' –

+0

@James Спасибо за эту статью, дадут ей прочитать. – xShinies

ответ

4

Вы видите неточность с плавающей запятой.

(720000 + 144000) * 0.285 фактически вычисляет до 246239.99999999997.
Чтение, что как double будет округлено при печати, но приведение к интегральному типу всегда будет усекать.

В зависимости от вашего прецедента, вы можете использовать decimal или вместо BigDecimal вместо двойной или просто круглой.

+0

Большое спасибо за ваш быстрый ответ! – xShinies

0

Потому что мне не разрешено комментировать, я собираюсь ответить на этот вопрос, который на самом деле просто основывается на том, что сказал Слэкс. Если по какой-либо причине вы обнаружите, что вам НЕОБХОДИМО использовать длинные, существует метод C# Math.Round, который будет округлять значение, которое затем даст вам ожидаемое значение. Конечно, округление не всегда является лучшим вариантом.

http://msdn.microsoft.com/en-us/library/75ks3aby%28v=vs.110%29.aspx

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