[解決済み] C/C++で標準の符号関数(signum, sgn)はありますか?
2022-03-20 05:28:46
質問
負の数には-1、正の数には+1を返す関数が欲しい。 http://en.wikipedia.org/wiki/Sign_function 自分で書くのは簡単だけど、標準ライブラリのどこかにあるような気がするんだ。
編集部:具体的には、浮動小数点数で動作する関数を探していたんです。
どのように解決するのですか?
タイプセーフのC++版です。
template <typename T> int sgn(T val) {
return (T(0) < val) - (val < T(0));
}
メリット
- Signum (-1、0、1) を実際に実装しています。ここでのcopysignを使った実装は-1か1しか返さないので、signumではありません。また、ここでのいくつかの実装はintではなくfloat(またはT)を返しており、無駄が多いように思われます。
- int、float、double、unsigned shorts、あるいは integer 0 から構成可能で orderable な任意のカスタム型に対して動作します。
-
速い!
copysign
は遅いです。特に、昇格してまた絞り込む必要がある場合は。これは分岐がなく、最適化が可能です。 - 標準規格に準拠 ビットシフトハックは巧妙ですが、いくつかのビット表現に対してのみ機能し、符号なし型を持っているときには機能しません。適切な場合には、手動で特殊化することも可能である。
- 正確であること ゼロとの単純な比較は、マシン内部の高精度表現(例えばx87の80ビット)を維持し、ゼロへの早すぎる丸めを回避することができます。
注意点
-
テンプレートなので、状況によってはコンパイルに時間がかかるかもしれません。
-
どうやら、新しく、やや難解で、非常に遅い標準ライブラリ関数を使用することを考える人がいるようだ シグナムを実装していない の方が理解しやすいと思います。
-
は
< 0
の部分をチェックすると、GCCの-Wtype-limits
の警告が表示されます。いくつかのオーバーロードを使用することでこれを回避することができます。template <typename T> inline constexpr int signum(T x, std::false_type is_signed) { return T(0) < x; } template <typename T> inline constexpr int signum(T x, std::true_type is_signed) { return (T(0) < x) - (x < T(0)); } template <typename T> inline constexpr int signum(T x) { return signum(x, std::is_signed<T>()); }
(これは最初の注意点の良い例です)。
関連
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] 整数の平方根が整数であるかどうかを判断する最速の方法
-
[解決済み] 標準C++/C++11,14,17/Cを使用してファイルが存在するかどうかを確認する最速の方法?
-
[解決済み】C言語の関数ポインタはどのように機能するのですか?
-
[解決済み】関数f(f(n))を設計する == -n
-
[解決済み】C言語のライブラリをPythonでラッピングする。C、Cython、またはctypes?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない