2012-04-09 4 views
-1

Теперь я знаю, как использовать метод float.Parse, но столкнулся с проблемой.Разбор строки в поплавке

Я разбираю строку «36.360», однако разобранный поплавок становится 36.3600006103516.

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

Очевидно, что я ищу разобранный поплавок, равный 36.360.

+3

О, извините, я положил его как ярлык и в названии. я не буду помещать его в следующий раз в заголовок – Abstract

ответ

1

Это связано с тем, что float или double хранятся таким образом, что это математический процесс для считывания значения из памяти. Если вы хотите сохранить значение в качестве фактического значения, лучшим выбором будет decimal.

согласно MSDN Page on System.Decimal:

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

+0

Причина для заключения этого ответа была вызвана фактом цитирования страницы msdn, а также указанием финансовых расчетов. Прекрасно ответил на ситуацию. Благодаря! – Abstract

+0

Я не уверен, что вы подразумеваете под «математическим процессом для чтения значения из памяти». Фактически, настоящая «проблема» с «float» и «double» заключается в том, что они хранят значения в виде дробей base-2 и что есть некоторые числа с конечным представлением base-10, но бесконечное представление base-2. – phoog

+0

@phoog. Я имел в виду, что когда процессор читает 'float' или' double' из памяти, он должен разбирать биты, чтобы вытащить Sign, Exponent и Mantissa, а затем выполнить математику, как показано на [Wikipedia] (http : //en.wikipedia.org/wiki/Double-precision_floating-point_format). Из-за задействованной математики вы получаете аппроксимацию значения, а не точное значение. Единственными точными значениями, которые могут предоставить 'float' или' double', являются 1 и мощность 2, и даже тогда это зависит от того, как процессор правильно выполняет математику. В то время как Integer в памяти всегда будет иметь точное значение. –

3

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

Wikipedia (любые много статей в Интернете) объясняют проблемы.

2

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

+2

«Никогда не быть равным» - популярное недоразумение. Есть миллиарды значений, которые 'float's могут хранить точно. Например, многие целые числа; вы можете хранить 1234567.0 в поплавке и получать точные результаты при сравнении. Они просто не очень хорошо хранят числа с плавающей запятой. –

+0

@MrLister +1, и, кроме того, многие дробные числа также могут быть представлены точно в двоичной системе с плавающей запятой (например, 0,5).Фактически, каждый шаблон с плавающим или двойным битом представляет либо бесконечность, NaN, либо некоторое точное числовое значение. – phoog

+0

@MrLister Правда, но есть миллиарды значений, которые 'float' не могут хранить точно, поэтому, если вы не можете гарантировать, что переменная содержит значение, которое может быть точно представлено 'float', использование сравнения равен приводит к большему количеству проблем чем это стоит. Пример кода: 'debug.print ((float) 3.141 == 3.141? True: false)' генерирует 'false', хотя очевидно (нам), что это должно быть правдой. – saluce

1

Существуют пределы точности чисел с плавающей запятой. За дополнительной информацией обращайтесь к this link.

Если вам нужно более точное отслеживание, рассмотрите возможность использования чего-то типа double или decimal.

1

Это не странная проблема, это всего лишь одна из очаровательных особенностей поплавков, с которыми вы всегда столкнетесь. floats не могут точно выразить такие десятичные значения!

Так что, если вам нужен результат, чтобы быть точно 36,36, использовать decimal, а не float.
В противном случае вы можете округлить. Обратите внимание, что округление не поможет, потому что после округления оно не будет равно 36.36.