Есть ли функция округления C, такая как функция округления MATLAB?

Мне нужна функция округления C, которая округляет числа, например, функция округления MATLAB. Есть ли один? Если вы не знаете, как работает круглая функция MATLAB, см. эту ссылку:

Функция раунда MATLAB

Я подумал, что мог бы просто написать свою собственную простую функцию раунда, чтобы соответствовать функциональности MATLAB.

Спасибо,

Демиовца


person DemiSheep    schedule 30.08.2010    source источник
comment
Почему ты не можешь написать такой сам?   -  person rkellerm    schedule 30.08.2010
comment
Потому что вы не пишете сами то, что предоставляется стандартной библиотекой.   -  person DevSolar    schedule 30.08.2010
comment
+1 за кажущийся простым вопрос, на который было получено много хороших ответов.   -  person Timothy    schedule 30.08.2010


Ответы (6)


Если в стандартной библиотеке нет функции round(), вы можете, имея дело с числами с плавающей запятой, произвольно оценить каждое значение, проанализировать число в месте после места, до которого вы хотите округлить, проверить, больше ли оно , равно или меньше 5; Затем, если значение меньше 5, вы можете floor() число, которое вы в конечном итоге ищете. Если значение цифры после места, до которого вы округляете, равно 5 или больше, вы можете перейти к функции floor() оцениваемого числа, а затем добавить 1.

Я прошу прощения за любую неэффективность, связанную с этим.

person Mr_Spock    schedule 30.08.2010
comment
Я думал сделать что-то вроде этого. Если значение больше 0,5, разве я не сделал бы просто ceil()? Как проверить десятичный разряд? Может быть, отрезать все число, а затем проверить, больше или меньше десятичное число 0,5? - person DemiSheep; 30.08.2010
comment
Если вы делаете что-то вроде разбиения числа, например 5,321, на массив, содержащий 4 элемента, каждый из которых содержит число в пределах вашего числа 5,321, то вы можете, если хотите округлить до ближайшего целого числа, оценить только 3. Найдите арифметику произвольной точности. Д. Э. Кнут написал текст на эту тему в книге «Искусство компьютерного программирования». Я полагаю, что это был Том 2, где он говорил об этом. В любом случае, вы в основном конвертируете 5.321 в строку, а затем обрабатываете каждый символ (за исключением десятичной точки) как его собственное значение (сначала вы должны преобразовать каждый символ в число, используя что-то вроде atoi()). - person Mr_Spock; 30.08.2010
comment
Это худший из возможных способов, тем более, что в стандартной библиотеке есть множество опций. (Вы могли проверить, прежде чем писать ответ.) Страшно то, что этот ответ действительно был принят... - person DevSolar; 07.09.2010

Это похоже на функцию round() из math.h.

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

Существует также функция lrint(), которая возвращает значение int, хотя lrint() и друзья подчиняются текущему направлению округления — вам нужно будет установить это с помощью fesetround() , различные направления округления можно найти здесь .

person nos    schedule 30.08.2010
comment
Что ж, round() также подчиняется fesetround(), а также множеству других функций, которые охватывают любую комбинацию параметра и возвращаемого типа. round() является особенным только в софере, поскольку это единственная функция из группы, к которой нет добавленных или предшествующих букв «l» или «f»... - person DevSolar; 30.08.2010
comment
В документах прямо указано, что round/roundf/roundl не заботится о текущем направлении округления. математическая функция без суффикса f или l обычно принимает в качестве аргумента двойное число. - person nos; 30.08.2010
comment
Вау. Спасибо, я пропустил эту маленькую деталь (раунд/раундф/раундл не соблюдает настройки ‹fenv.h›.) - person DevSolar; 30.08.2010

Ознакомьтесь со стандартным заголовком <fenv.c>, особенно с функцией fesetround() и четырьмя макросами FE_DOWNWARD, FE_TOWARDZERO, FE_TONEAREST и FE_UPWARD. Это определяет, как значения с плавающей запятой округляются до целых чисел. Убедитесь, что ваша реализация (например, компилятор C/библиотека C) действительно поддерживает это (проверив возвращаемое значение fesetround() и документацию по вашей реализации).

Функции, учитывающие эти настройки, включают (из <math.h>):

  • llrint()
  • llrintf()
  • llrintl()
  • lrint()
  • lrintf()
  • lrintl()
  • rint()
  • rintf()
  • rintl()
  • llround()
  • llroundf()
  • llroundl()
  • lround()
  • lroundf()
  • lroundl()
  • nearbyint()
  • nearbyintf()
  • nearbyintl()

в зависимости от ваших потребностей (тип параметра и тип возвращаемого значения, с неточным исключением с плавающей запятой или без него).

ПРИМЕЧАНИЕ: round(), roundf() и roundl() выглядят так, как будто они принадлежат к приведенному выше списку, но эти три не учитывают режим округления, установленный fesetround() !!

Точные подробности см. в документации по вашей самой любимой стандартной библиотеке.

person DevSolar    schedule 30.08.2010

Нет, C (до C99) не имеет функции round. Типичный подход примерно такой:

double sign(double x) { 
    if (x < 0.0)
        return -1.0;
    return 1.0;
}

double round(double x) { 
    return (long long)x + 0.5 * sign(x);
}

Это округляется до целого числа, предполагая, что исходное число находится в диапазоне, который может быть представлен long long. Если вы хотите округлить до определенного количества знаков после запятой, это может быть немного сложнее. Если числа не слишком велики и не слишком малы, вы можете умножить их на 10N, округлить до целого числа и снова разделить на 10N (учитывая, что это может внести некоторые собственные ошибки округления).

person Jerry Coffin    schedule 30.08.2010
comment
Эээ... В C есть функция round(). - person DevSolar; 30.08.2010
comment
C (по крайней мере, c99) наверняка имеет round/roundf/roundl, а также lrint/llrint и тому подобное. - person nos; 30.08.2010
comment
C99 да, но C89/90 наверняка нет. Учитывая количество реализаций, которые все еще относятся к C89/90, знание того, как сделать это самостоятельно, по-прежнему весьма полезно. - person Jerry Coffin; 30.08.2010
comment
Увы, сквайр, время идет. Когда кто-то задает вопрос на C, я предполагаю, что он имеет в виду наполовину обновленную реализацию. - person DevSolar; 30.08.2010
comment
Увы, плут, время течет медленно. Основываясь на реальных реализациях, предполагать, что кто-то использует C99, довольно глупо. Ни одна из двух больших компаний (Gnu и Microsoft) даже не близка к полному соответствию C99. pcc находится в парадоксальном положении, реализовав практически все новые функции C99, но по-прежнему не имея многих важных функций C89/90. Единственной доступной достаточно полной реализацией C99 является Comeau с библиотекой Dinkumware C99. Я много лет пользуюсь Comeau, но хорошо знаю, как мало других. - person Jerry Coffin; 30.08.2010
comment
С этой точки зрения, мы вообще не должны отвечать на вопросы о C++, потому что существует только одна реализация (опять же Comeau или, скорее, его интерфейс EDG), которая полностью реализует C++ (98). («Экспорт»… моя любимая мозоль.) У меня есть некоторая проблема с общими утверждениями, такими как количество реализаций… или даже близко к полному соответствию. Можете что-нибудь сказать о статусе поддержки округления? Если нет, я считаю, что ваши утверждения вводят в заблуждение. - person DevSolar; 30.08.2010
comment
@DevSolar: это зависит от библиотеки, а не от компилятора. Тот, который распространяет Microsoft, этого не делает. С Gnu библиотека, которую вы получаете, зависит от используемого вами порта. Например, в Windows у cygwin есть поддержка округления, а у MinGW нет (или не было, когда я в последний раз смотрел). В других системах имена меняются, но ситуация не меняется — по крайней мере, из того, что я видел, разрыв между наличием и отсутствием, вероятно, составляет примерно 40:60. - person Jerry Coffin; 30.08.2010
comment
@DevSolar: что касается ответа на вопрос о C ++, я занимаю примерно ту же позицию, что и в этом: да, export есть в стандарте, но нет, я не предполагаю, что он есть у большинства людей. Если я упоминаю export, я обычно говорю что-то вроде: Теоретически вы должны использовать export, но в большинстве реализаций C++ этого нет, поэтому вам нужно поместить все определения шаблонов в заголовки. - person Jerry Coffin; 30.08.2010
comment
Тем не менее, утверждение C не имеет функции раунда совершенно неверно и вводит в заблуждение. - person DevSolar; 07.09.2010

Если я не ошибаюсь, вы ищете что-то вроде пол и потолок, и вы их найдете в 1_

person rano    schedule 30.08.2010

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

Y = round(X) округляет элементы X до ближайших целых чисел.

Не во множественном числе: как и обычные операции MATLAB, он работает со всеми элементами матрицы. Эквиваленты C, опубликованные выше, имеют дело только с одним значением одновременно. Если вы можете использовать C++, ознакомьтесь с Valarray. Если нет, то старый добрый цикл for — ваш друг.

person André Caron    schedule 31.08.2010