Как мне округлить поплавок в этом случае? - PullRequest
2 голосов
/ 30 марта 2012

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

  • 0.0299999400
  • 0.0300000000

Мне не важна большая точность, янужно вычислить CRC этих чисел, и они должны быть одинаковыми, поэтому мой подход заключался в использовании этого кода:

private static float Rounding(float v, float p)
{
    return Mathf.Round (v * p) / p; 
}

Где p - моя точность.

Это, кажется, работает хорошо, но в этом случае, если бы я использовал p = 1e7 , умножение первого числа привело бы к 299999.4 и округлилось бы до 299999 , став 0,0299999 , тогда как 0,03 останется 0,03 .Это моя проблема.

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

Однако я знаю, что мои значения с плавающей точкой находятся в диапазоне, который не так велик, как диапазон с плавающей точкой (от ± 1,5e-45 до ± 3,4e38).Я имею в виду, что если я знаю, что мой диапазон поплавков равен [-100;+100], могу предположить, что десятичных цифр будет достаточно, чтобы p было 3 .Это правильно?

Есть ли другой способ сделать это?

Ответы [ 2 ]

4 голосов
/ 30 марта 2012

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

0 голосов
/ 30 марта 2012

Я не знаю, правильно ли я вас понимаю, но если вам нужно, чтобы эти два числа считались равными, вы можете использовать:

Math.Round(Convert.ToDecimal((float)0.0299999400),2); //result is 0.03
Math.Round(Convert.ToDecimal((float)0.0300000000),2); //result is 0.03

И вот оно у вас.Если вы хотите округлить свои числа с точностью до 1e7, тогда эти два числа будут отличаться.

...