Signbit c что это
Существует ли стандартная функция знака (signum, sgn) в C/C++?
Edit: в частности, я искал функцию, работающую на поплавках.
23 ответов
удивлен никто не оставил дистанционных, типобезопасный язык C++ версия:
(что является хорошим примером первого предостережения.)
Я не знаю стандартной функции для этого. Вот интересный способ написать это:
вот более читаемый способ сделать это:
Если вам нравится тернарный оператор, вы можете сделать это:
существует функция математической библиотеки C99, называемая copysign (), которая берет знак из одного аргумента и абсолютное значение из другого:
похоже, что большинство ответов пропустили исходный вопрос.
существует ли стандартная функция знака (signum, sgn) в C/C++?
более быстро чем вышеуказанные решения, включая самое высокое расклассифицированное одно:
есть способ сделать это без ветвления, но это не очень красиво.
много других интересных, слишком умных вещей на этой странице тоже.
существует ли стандартная функция знака (signum, sgn) в C/C++?
да, в зависимости от определения.
C99 и позже имеет signbit() макрос
int signbit (real-floating x );
The signbit макрос возвращает ненулевое значение тогда и только тогда, когда знак его значения аргумента отрицательный. C11 §7.12.3.6
тем не менее OP хочет что-то немного отличающийся.
глубже:
в общем, в C/C++ нет стандартной функции signum, и отсутствие такой фундаментальной функции говорит вам много об этих языках.
кроме того, я считаю, что обе точки зрения большинства о правильном подходе к определению такой функции в некотором роде правильны, и «спор» об этом на самом деле не является аргументом, как только вы учитываете два важных предостережения:
довольно близко, да?
нет, он не существует в c++, как в matlab. Для этого я использую макрос в своих программах.
принятый ответ с перегрузкой ниже действительно не вызывает — Wtype-limits однако он запускает -Wunused-параметр на
немного не по теме, но я использую этот:
нет приведения для неподписанных типов и никакого дополнительного минуса.
на самом деле у меня есть этот кусок кода, используя ГГС()
зачем использовать тернарные операторы и if-else, когда вы можете просто сделать это
эта функция предполагает:
в то время как целочисленное решение в принятом ответе довольно элегантно, меня беспокоило, что оно не сможет вернуть NAN для двойных типов, поэтому я немного изменил его.
Catalina C ++: использование заголовков приводит к ошибке: в глобальном пространстве имен нет члена с именем signbit
После обновления до Каталины из Мохаве, настройка: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk в env.
Я не могу скомпилировать программу, которая использует заголовок.
Я попытался изменить CFLAGS, CCFLAGS, CXXFLAGS, чтобы они указывали на расположение MacOSSDK, которое ничего не меняет
например, макрос: isless присутствует в глобальном пространстве имен и на моем компьютере:
Даже заголовок cmath включает его:
Вы должны указать систему сборки кода, который вы пытаетесь скомпилировать, на правильные заголовки:
(1) Убедитесь, что Xcode обновлен. Невозможно сказать, что может сделать устаревший Xcode на Catalina для вашей среды сборки.
Если это решит проблему, вы можете найти лучший способ сделать это в CMake.
Конечно, если вы любите приключения, вы также можете отключить SIP, как предложено в ответе на мой вопрос: / usr / include отсутствует в macOS Catalina (с Xcode 11)
У меня возникла та же проблема при попытке нацелить iOS (как на MacBook Air, так и на GitHub Actions runner), и вот еще несколько соображений по этой проблеме, хотя я недостаточно знаком с экосистемой Apple, чтобы предложить правильное решение. Исходная командная строка исходила от CMake в cpprestsdk, но как только я свел ее к основам, вот короткое повторение.
Когда я запускаю его, я знакомлюсь со многими, сталкивающимися с той же проблемой:
Существуют только две директории include, которые я передаю в исходной командной строке:
Но интересными моментами здесь являются несуществующие каталоги включения, о которых он сообщает, а также каталоги включения, которые он в конечном итоге ищет, и их порядок. Я предполагаю, что дополнительные каталоги, не упомянутые в командной строке, вставляются драйвером Apple Clang на основе определенной логики Apple.
Из сообщения об ошибке видно, что заголовок находится по адресу: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/cmath и в строке 304 его можно увидеть:
Если вы посмотрите на первые 2 записи в найденных каталогах:
Теперь, если вы посмотрите на список игнорируемых каталогов, самая первая запись в этом списке:
из которых последняя c++/v1 часть не существует на моем компьютере, поэтому я задаюсь вопросом, должна ли установка iPhone SDK создать символическую ссылку c++ внутри существующей части пути, чтобы указать /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++ каталог, чтобы все это работало.
Во всяком случае, это то, что я думаю, что происходит, и мне интересно, если кто-нибудь знает, как правильно это исправить?
Is there a standard sign function (signum, sgn) in C/C++?
Edit: Specifically, I was looking for a function working on floats.
21 Answers 21
Surprised no one has posted the type-safe C++ version yet:
(Which is a good example of the first caveat.)
I don’t know of a standard function for it. Here’s an interesting way to write it though:
Here’s a more readable way to do it:
If you like the ternary operator you can do this:
There is a C99 math library function called copysign(), which takes the sign from one argument and the absolute value from the other:
It seems that most of the answers missed the original question.
Is there a standard sign function (signum, sgn) in C/C++?
Apparently, the answer to the original poster’s question is no. There is no standard C++ sgn function.
Is there a standard sign function (signum, sgn) in C/C++?
Yes, depending on definition.
C99 and later has the signbit() macro in
int signbit (real-floating x );
The signbit macro returns a nonzero value if and only if the sign of its argument value is negative. C11 §7.12.3.6
Yet OP wants something a little different.
Deeper:
Faster than the above solutions, including the highest rated one:
There’s a way to do it without branching, but it’s not very pretty.
Lots of other interesting, overly-clever stuff on that page, too.
In general, there is no standard signum function in C/C++, and the lack of such a fundamental function tells you a lot about these languages.
Apart from that, I believe both majority viewpoints about the right approach to define such a function are in a way correct, and the «controversy» about it is actually a non-argument once you take into account two important caveats:
A signum function should always return the type of its operand, similarly to an abs() function, because signum is usually used for multiplication with an absolute value after the latter has been processed somehow. Therefore, the major use case of signum is not comparisons but arithmetic, and the latter shouldn’t involve any expensive integer-to/from-floating-point conversions.
_putch, _putwch
Записывает символ в строку.
Этот API нельзя использовать в приложениях, выполняемых в среде выполнения Windows. Дополнительные сведения: Функции CRT, которые не поддерживаются в приложениях универсальной платформы Windows.
Синтаксис
Параметры
c
Символ, который требуется вывести.
Возвращаемое значение
Возвращает значение c в случае успешного выполнения. При сбое _putch возвращается EOF; Если _putwch не выполняется, возвращается значение WEOF.
Remarks
Эти функции записывают символ c напрямую, без буферизации, в консоль. В Windows NT функция _putwch записывает символы Юникода, используя текущие настройки языкового стандарта консоли.
Версии с суффиксом _nolock идентичны за исключением того, что они не защищены от помех со стороны других потоков. Дополнительные сведения см. в разделе _putch_nolock, _putwch_nolock.
По умолчанию глобальное состояние этой функции ограничивается приложением. Чтобы изменить это, см. раздел глобальное состояние в CRT.
Универсальное текстовое сопоставление функций
Процедура Tchar.h | _UNICODE и _MBCS не определены | _MBCS определено | _UNICODE определено |
---|---|---|---|
_puttch | _putch | _putch | _putwch |
Требования
Подпрограмма | Обязательный заголовок |
---|---|
_putch | |
_putwch |
Дополнительные сведения о совместимости см. в разделе Compatibility.
Стандарт C++20: обзор новых возможностей C++. Часть 1 «Модули и краткая история C++»
25 февраля автор курса «Разработчик C++» в Яндекс.Практикуме Георгий Осипов рассказал о новом этапе языка C++ — Стандарте C++20. В лекции сделан обзор всех основных нововведений Стандарта, рассказывается, как их применять уже сейчас и чем они могут быть полезны.
При подготовке вебинара стояла цель сделать обзор всех ключевых возможностей C++20. Поэтому вебинар получился насыщенным. Он растянулся на почти 2,5 часа. Для вашего удобства текст мы разбили на шесть частей:
Update. К статье добавлены правки и комментарии Антона Полухина.
Краткая история C++
В самом начале я задал слушателям вебинара вопрос: сколько всего существует стандартов C++?
Давайте посчитаем. Бьёрн Страуструп занялся разработкой C++ в восьмидесятых годах. К нему пришли люди из ISO [международная комиссия по стандартизации] и предложили стандартизировать язык. Так и появился C++98 — первый Стандарт.
Прошло пять лет, и Стандарт исправили. Получился C++03. Это было не что-то революционное, а просто исправление ошибок. Кстати, иногда C++03 не считают отдельным Стандартом. Возможно, C++03 — самый популярный Стандарт с точки зрения примеров в интернете и ответов на Stack Overflow, но назвать его современным C++ сейчас невозможно.
Всё изменил следующий Стандарт, который планировалось выпустить до 2010 года. Он носил кодовое название C++0x, которое потом сменилось на C++1x. Решить все проблемы и издать Стандарт смогли только в 2011 году, он получил название C++11. Заметно расширились возможности языка: там появились auto, move-семантика, variadic templates. Когда я учил этот Стандарт, у меня возникло ощущение, что освоить C++11 равносильно изучению нового C++.
Прошло три года. Вышел C++14. Он не стал таким революционным и в основном содержал фиксы ошибок, неизбежных при принятии такого огромного набора документов, как C++11. Но и в 2014 году добавилось новое.
Ещё через три года C++17 добавил больше интересных вещей: дополнительные возможности стандартной библиотеки, распаковку при присваивании и прочее.
Логично ожидать, что за большим Стандартом последует Стандарт с исправлениями ошибок. Но что-то пошло не так. C++20 — это практически новый язык. По количеству нововведений он сравним с C++11, а может быть, обгоняет его.
Мы рассмотрим несколько ключевых возможностей C++20. Их список есть в анонсе: это модули, концепты, ranges, корутины. Также будет дан краткий обзор всего, что не вошло в этот список: другие фичи ядра и стандартной библиотеки. Пойдём по порядку.
Модули
Мотивация
В итоге использование хедеров:
Что у других
Посмотрим на ситуацию в других языках — ведь модули есть везде. Для примера возьмём Python. Мне нравится, как модули реализованы в нём. Есть возможность импортировать модуль целиком или ограничиться определёнными именами. При импорте имена можно переназвать. На слайде вы видите небольшой пример.
Или рассмотрим Fortran. Выбор может показаться неожиданным, но почему бы не рассмотреть его, раз такой язык существует, и в нём есть модули. Сам Fortran появился в 1957 году, а модули ввели в 1991-м. Соответственно, схему придумали когда-то между этими двумя датами. Пример на слайде — просто иллюстрация, к модулям она не относится.
В Fortran единицу трансляции можно скомпилировать только в том случае, если все зависимости уже скомпилированы. Из-за этого появилось правило run make until it succeeds, то есть нужно продолжать запускать make, пока наконец не скомпилируется. В первый раз скомпилируются модули, у которых нет зависимостей, во второй раз — модули, которые зависели от первых. В какой-то момент вся программа соберётся. Если повезёт, даже раньше, чем вы ожидаете.
Как вы думаете, по какому пути пошёл C++?
Конечно же, по пути Фортрана! Хотя за три десятка лет в Фортране как-то научились обходить проблемы модулей, фортрановские решения для C++ не годятся — ситуация сложнее.
«C++ не был бы C++ если бы всё было так просто. Модули пошли по пути Фортрана и Питона. Синтаксис модулей специально затачивался на то, чтобы можно было создать сборочные системы, автоматически выводящие зависимости между модулями и автоматически их собирающие — то есть, это путь Питона. Однако, пока такие инструменты не появились, есть возможность указывать зависимости и правила сборки вручную».
Но не всё так плохо.
Пример
При компиляции примера нужно вначале собрать модуль foo2.cppm, потому что он ни от чего не зависит. Затем нужно собрать foo.cppm и только потом bar.cpp.
Поэтому компилировать проект с модулями нужно два раза. Появляется новая операция — предкомпиляция. На слайде я привёл команды для сборки этой программы компилятором Clang.
Эта концепция полностью ломает некоторые из существующих систем сборки C++ кода. Хотя всё налаживается. К примеру, в CMake добавили экспериментальную поддержку модулей. Такие системы, как Build2, b2, cxx_modules_builder, xmake, Meson, autotools, Tup, Scons, уже поддерживают модули.
Теория
Рассмотрим, какие проблемы модули решают, а какие не решают. Зададим вопросы.
Следующий блок вопросов.
Модули нарушают несколько устоявшихся принципов C++:
Модули добавляют новые понятия. Например, новые типы единиц трансляции — они называются module unit и header unit. Появился тип компоновки module linkage.
Module unit бывают двух типов:
В большинстве случаев module implementation unit вообще не понадобится. Он предназначен для больших модулей, код которых сам по себе требуется структурировать. Поэтому чаще всего один модуль — один module interface unit.
Посмотрим на допустимый формат импорта и экспорта из модулей.
Модуль и любые cpp-файлы могут импортировать другие модули и, внезапно, заголовочные файлы. Последнее, к сожалению, мне пока не удалось протестировать — у компиляторов явно какие-то проблемы.
Интересно, что при этом импортируются макросы — то, от чего нас пытается избавить новый Стандарт. По легенде комитет по стандартизации рассматривал полное исключение импорта макросов, но представители крупных компаний попросили не делать этого.
В отличие от #include, при импорте нужна точка с запятой.
Можно экспортировать шаблоны. А значит, экспорт — это не просто сохранение сигнатуры. Если мы экспортируем шаблон, то должен быть сохранён весь его код, потому что позднее при настройке шаблона он понадобится. Таким образом, предкомпиляция — это не компиляция, она сохраняет всю выразительность C++ кода.
Посмотрим на примерах. Из модулей экспортируются:
Тут можно найти ещё одно применение безымянным namespace.
Такая конструкция допустима в преамбуле. Текущий модуль будет экспортировать всё то, что экспортирует вызванный.
Таким образом, имена тоже экспортируются: для этого пишите :: перед именем, потому что using требует указания пространства имён.
Во многих языках модули поддерживают структурирование. Например, в Java есть пакет, названный так: com.sun.tools.javac.util. В C++ есть целых два типа структурирования. Во-первых, имя модуля может как и в Java состоять из нескольких идентификаторов, разделённых точкой:
Во-вторых, модули поддерживают партиции, которые указываются через двоеточие после имени модуля. Партиции служат для структурирования внутри модуля и не видны вне него.
Статус
«std.core это расширение Стандарта. Код, использующий его, скорее всего перестанет компилироваться через пяток лет».
В GCC поддержки модулей нет в trunk, но есть в ветке. Эту ветку планируют влить в GCC 11.
В Clang модули присутствуют давно. Вообще даже техническая спецификация модулей, принятая в C++20, далеко не первая. Их давно обсуждали и даже планировали включить в Стандарт C++17, но не успели. Clang поддерживает обе спецификации: новую и старую, но всё равно не полностью.
Насколько мне известно, ни один из компиляторов не поддерживает модули полностью. Я считаю, что время модулей пока не пришло. Модули — сырая фича, которая не везде реализована хорошо, хотя все основные компиляторы уже о ней отчитались. Будем надеяться, что вскоре мы сможем полноценно пользоваться модулями.
Заключение
Во время трансляции мы провели голосование, крутая это фича или нет. Результаты опроса:
«У модулей есть и другое, очень важное достоинство: они позволяют скрывать детали реализации. Всё, что выносили в заголовочных файлах в namespace impl или detail — с модулями можно совсем спрятать».
Главный минус: существенно усложняется процесс сборки. С их активным применением я бы пока подождал.