Я пытаюсь найти поплавок с помощью математического раунда. Я нашел следующее

0.5 --> 0
1.5 --> 2
2.5 --> 2
3.5 --> 4

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

6
Kuzon 18 Авг 2014 в 16:18
1
Что вы ожидаете? Что вы подразумеваете под «правильным округлением четных чисел»? (на самом деле они «правильно округляются» в вашем примере для «правильно» определенного как «средние точки идут к ближайшему четному числу»).
 – 
Pascal Cuoq
18 Авг 2014 в 16:22
Огромное спасибо за быстрые ответы! Я чувствую себя немного глупо сейчас, никогда не слышал об этом раньше. Не так, как меня учили в школе :)
 – 
Kuzon
18 Авг 2014 в 16:24

4 ответа

Лучший ответ

Из документации;

Ближайшее к a целое число. Если дробная составляющая равна половине между двумя целыми числами, одно из которых четное, а другое нечетное, тогда возвращается четное число. Обратите внимание, что этот метод возвращает Double вместо целого типа.

Метод Math.Round имеет несколько перегрузок, требующих MidpointRounding в качестве параметра, в котором вы можете указать значение округления, если оно находится посередине между двумя числами.

AwayFromZero 

Когда число находится на полпути между двумя другими, оно округляется до ближайшего числа, отличного от нуля.

ToEven

Когда число находится на полпути между двумя другими, оно округляется до ближайшего четного числа.

11
Soner Gönül 18 Авг 2014 в 16:36
3
Интересно, что происходит, когда он находится на полпути между двумя целыми числами, оба из которых четные... Избыточность FTW!
 – 
Kendall Frey
18 Авг 2014 в 16:23
А почему говорят "дробная составляющая а", а не просто "а"? Как бы то ни было, утверждение кажется неверным: например, если a = 3.5, дробная часть a равна 0.5, и строгое прочтение этого предложения может натолкнуть вас на мысль, что 0.0 возвращается. (Жалоба на содержимое MSDN, а не на этот ответ.)
 – 
Mark Dickinson
18 Авг 2014 в 20:59

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

Math.Round(value, MidpointRounding.AwayFromZero);

Используя вышеупомянутое:

Когда число находится на полпути между двумя другими, оно округляется до ближайшего числа, отличного от нуля.

Дополнительную документацию по перечислению MidpointRounding см. В здесь.

6
Christos 18 Авг 2014 в 16:20
Большое спасибо, я думал, что это была плавающая точка после небольшого исследования. Даже не подумал проверить документацию! Сожалею!!
 – 
Kuzon
18 Авг 2014 в 16:23
Теперь продолжим тест :)
 – 
Kuzon
18 Авг 2014 в 16:26

Вы можете попробовать вот так

 Math.Round(value, MidpointRounding.AwayFromZero);

Из MSDN

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

Также, чтобы упомянуть один важный момент, который, как мне кажется, стоит упомянуть, это то, что Microsoft следовала Стандарт IEEE 754 . Это также упоминается в MSDN для Math.Round в разделе «Примечания», в котором говорится:

Округлить до ближайшего, связать с четным - округление до ближайшего значения; если число падает на полпути, оно округляется до ближайшего значения с помощью четный (нулевой) младший бит, который встречается в 50% случаев; это является значением по умолчанию для двоичных чисел с плавающей запятой и рекомендуемым значением по умолчанию для десятичного числа.

Округлить до ближайшего, от нуля до нуля - округление до ближайшего значения; если число падает на полпути, оно округляется до ближайшего значения выше (для положительных чисел) или ниже (для отрицательных чисел); это предназначена как опция для десятичных чисел с плавающей запятой.

2
Rahul Tripathi 18 Авг 2014 в 16:28

Это называется банковским округлением (округлением до четного). Подробнее об этом можно узнать здесь. Это функция .NET Framework, которая работает должным образом.

0
Randy Minder 18 Авг 2014 в 16:20
4
Ну, это особенность фреймворка. Это не часть языка С#.
 – 
Jon Skeet
18 Авг 2014 в 16:21
Спасибо Джон - исправил мой ответ
 – 
Randy Minder
18 Авг 2014 в 16:23