Почему Math.round возвращает long, а Math.floor возвращает double? - PullRequest
34 голосов
/ 05 августа 2010

Почему несоответствие?

Ответы [ 3 ]

17 голосов
/ 05 августа 2010

Нет противоречий: методы просто разработаны с учетом различных спецификаций.

  • long round(double a)
    • Возвращает ближайший long каргумент.
  • double floor(double a)
    • Возвращает наибольшее (самое близкое к положительной бесконечности) double значение, которое меньше или равноаргумент и равно математическому целому числу.
    • Сравните с double ceil(double a)
  • double rint(double a)
    • Возвращает значение double, наиболее близкое по значению к аргументу и равное математическому целому числу

Таким образом, по расчету round округляет до long и rint округляет до double.Это всегда имело место с JDK 1.0.

В JDK 1.2 были добавлены другие методы (например, toRadians, toDegrees);другие были добавлены в 1.5 (например, log10, ulp, signum и т. д.), и еще некоторые были добавлены в 1.6 (например, copySign, getExponent, nextUp и т. д.) (ищите С: метаданные в документации);но round и rint всегда имели друг друга такими, какими они являются сейчас с самого начала.

Возможно, возможно, вместо long round и double rint, было бы более "последовательным"Назовите их double round и long rlong, но это аргументировано.Тем не менее, если вы настаиваете на категорическом названии этого «несоответствия», то причина может быть такой же неудовлетворительной, как «потому что это неизбежно».

Вот цитата из Effective Java 2nd Edition, Item 40:Тщательно подписывайте метод проектирования :

В случае сомнений обращайтесь к руководствам API библиотеки Java.Хотя существует множество несоответствий - неизбежных, учитывая размер и область применения этих библиотек, - существует также значительное количество консенсуса.

Относительно связанные вопросы

5 голосов
/ 17 марта 2012

floor было бы выбрано, чтобы соответствовать стандартной подпрограмме c в math.h (rint, упомянутое в другом ответе, также присутствует в этой библиотеке и возвращает double,как в java).

, но round не было стандартной функцией в c в то время (это не упоминается в C89 - идентификаторы и стандарты c ; c99 действительно определяет round ион возвращает double, как и следовало ожидать).дизайнеры языка «заимствуют» идеи, так что, может быть, это исходит от какого-то другого языка?Фортран 77 не имеет функции с таким именем, и я не уверен, что еще тогда использовалось бы в качестве ссылки.возможно vb - у которого есть Round, но, к сожалению для этой теории, он возвращает double (php тоже).Интересно, что perl намеренно избегает определения раунда .

[обновление: хммм.выглядит как smalltalk возвращает целые числа .я не знаю достаточно о smalltalk, чтобы знать, является ли это правильным и / или общим, и метод называется rounded, но это может быть источником. smalltalk действительно повлиял на java в некотором смысле (хотя и более концептуально, чем в деталях).]

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

другими словами: функцииобщие для java и c обычно соответствуют стандарту c библиотеки в то время;остальные кажутся произвольными, но эта конкретная морщина может возникла из небольшой беседы.

1 голос
/ 17 марта 2012

Я согласен, что странно, что Math.round(double) возвращает long. Если большие значения double приводятся к long (что неявно делает Math.round), возвращается Long.MAX_VALUE. Альтернативой является использование Math.rint() во избежание этого. Однако Math.rint() имеет несколько странное поведение округления: связи устанавливаются округлением до четного целого числа, то есть 4.5 округляется до 4,0, а 5,5 округляется до 6,0). Другой альтернативой является использование Math.floor(x+0.5). Но имейте в виду, что 1,5 округляется до 2, а -1,5 округляется до -1, а не до -2. Еще одна альтернатива - использовать Math.round, но только если число находится в диапазоне между Long.MIN_VALUE и Long.MAX_VALUE. Значения с плавающей запятой двойной точности вне этого диапазона в любом случае являются целыми числами.

К сожалению, почему Math.round() возвращает long неизвестно. Кто-то принял это решение, и он, вероятно, никогда не давал интервью, чтобы рассказать нам, почему. Я предполагаю, что Math.round был разработан, чтобы обеспечить лучший способ (то есть, с округлением) для преобразования двойных в длинные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...