Вопрос

Может кто-нибудь объяснить, почему int (0.4 * 10.0) является 4 еще int ((2.4 - 2.0) * 10.0) является 3?

И еще, пожалуйста, объясните, как получить 4.то естьМне действительно нужно сделать int (System.Math.Round((2.4 - 2.0) * 10.0))?

Это так уродливо для того, что должно быть таким простым.

Это было полезно?

Решение

Двойное представление 2,4–2,0 равно 0,399999999999.Когда вы конвертируете число в целое число, десятичная часть усекается, поэтому 3,999999999 усекается до 3.

Другие советы

И еще, пожалуйста, объясните, как получить 4.то естьМне действительно нужно сделать

int (System.Math.Round((2,4 - 2,0) * 10,0))

это так уродливо для того, что должно быть таким простым.

Конечно нет, просто определите

let round x = int System.Math.Round(x)

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

2.4m - 2.0m == 0.4m
2.4 - 2.0   != 0.4

Чтобы скрыть float номер на int использовать:

let i = Convert.ToInt32(f)

Числа с плавающей запятой не имеют бесконечной точности.Некоторые числа могут быть представлены идеально (все, что включает степени двойки, например1, 1/2 = 0,5, 1/4 = 0,25 и т. д.), а другие не могут (например,1/3 не может быть точно разложена в конечную последовательность степеней двойки).Часто обрезка конца бесконечного ряда приводит к тому, что закодированная версия числа оказывается немного меньше его истинного значения.

Объедините это с тем фактом, что оператор (int) усекает, а не округляет, и вы можете столкнуться со случаями, когда операция, должен Результатом 4.0 вместо этого будет 3.999999999991, что станет 3.

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

Поскольку это проблема с представлениями с плавающей запятой, это справедливо не только для F#, но и для C#, (IIRC) Java и других языков.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top