cp-library

競技プログラミング用 C++ ライブラリ

View the Project on GitHub qandori/cp-library

:warning: 整数演算の共通部品

components/integer_arithmetic.hpp · GitHub で見る

共通ページ

整数除算 と 等比数列の和 が使う内部部品です。通常は各ライブラリの公開 API を使ってください。

全て integer_arithmetic_detail 名前空間にあります。

型・操作 内容
integer<T> bool 以外の組込み整数型および __int128_t・__uint128_t なら true となる bool 定数
add(a, b) 同じ型 T の const T& を 2 つ受け取り、和を T で返す
multiply(a, b) 同じ型 T の const T& を 2 つ受け取り、積を T で返す

add・multiply は integer<T> が true の場合、演算結果が T に収まらなければ std::overflow_error を送出します。それ以外の型はそれぞれ a + b・a * b を評価し、型自身の演算規則に従います。型の演算が対応していれば constexpr で使えます。既定引数はありません。

組込み整数型と 128 bit 整数型では各操作が \(O(1)\) 時間・追加空間です。他の型では、その型の加算・乗算および返り値の構築に必要な時間・空間を使います。

コード

#ifndef INTEGER_ARITHMETIC_HPP
#define INTEGER_ARITHMETIC_HPP

#include <cstdint>
#include <stdexcept>
#include <type_traits>

namespace integer_arithmetic_detail {

template <class T>
inline constexpr bool integer = (std::is_integral_v<T> || std::is_same_v<T, __int128_t> || std::is_same_v<T, __uint128_t>) && !std::is_same_v<T, bool>;

template <class T>
constexpr T add(const T &a, const T &b) {
	if constexpr (integer<T>) {
		T result;
		if (__builtin_add_overflow(a, b, &result)) throw std::overflow_error("integer addition");
		return result;
	} else return a + b;
}

template <class T>
constexpr T multiply(const T &a, const T &b) {
	if constexpr (integer<T>) {
		T result;
		if (__builtin_mul_overflow(a, b, &result)) throw std::overflow_error("integer multiplication");
		return result;
	} else return a * b;
}

}

#endif
Back to top page