- cmath[meta header]
- std[meta namespace]
- function[meta id-type]
namespace std {
float
modf(float value, float* iptr); // (1) C++03からC++20まで
double
modf(double value, double* iptr); // (2) C++03からC++20まで
long double
modf(long double value,
long double* iptr); // (3) C++03からC++20まで
constexpr floating-point-type
modf(floating-point-type value,
floating-point-type* iptr); // (4) C++23
double
modf(Integral value, double* iptr); // (5) C++11
constexpr double
modf(Integral value, double* iptr); // (5) C++23
float
modff(float value, float* iptr); // (6) C++17
constexpr float
modff(float value, float* iptr); // (6) C++23
long double
modfl(long double value,
long double* iptr); // (7) C++17
constexpr long double
modfl(long double value,
long double* iptr); // (7) C++23
}- Integral[italic]
浮動小数点数を、整数部と小数部に分解する。
- (1) :
floatに対するオーバーロード - (2) :
doubleに対するオーバーロード - (3) :
long doubleに対するオーバーロード - (4) : 浮動小数点数型に対するオーバーロード
- (5) : 整数型に対するオーバーロード (
doubleにキャストして計算される) - (6) :
float型規定 - (7) :
long double型規定
引数valueの小数部を符号付きとして返す。また、引数valueの整数部を*iptrに書き込む。
この関数によって返される整数部と小数部は、どちらも引数valueと同じ符号を持つ。
-
C++11 以降では、処理系が IEC 60559 に準拠している場合(
std::numeric_limits<T>::is_iec559() != false)、以下の規定が追加される。(複号同順)value = ±∞の場合、戻り値は±0となり、*expには±∞が設定される。valueが NaN の場合、戻り値は NaN となり、*expには NaN が設定される。- 戻り値は正確で、現在の丸め方式には依存しない。
-
C++11 で
valueが整数型のオーバーロードが追加されているが、iptrの型によって呼び出されるオーバーロードが一意に決まるため、存在意義は無いものと思われる。
(valueに整数型、iptrにnullptrを渡した場合のみ当該オーバーロードによって呼び出しが曖昧ではなくなるが、その場合は未定義動作となってしまうため、本オーバーロードの存在はむしろ有害) -
C++23では、(1), (2), (3)が(4)に統合され、拡張浮動小数点数型を含む浮動小数点数型へのオーバーロードとして定義された
#include <iostream>
#include <cmath>
int main()
{
// 正の浮動小数点数を、整数部と小数部に分解する
{
float x = 1.23f;
float integral_part = 0;
float fractional_part = std::modf(x, &integral_part);
std::cout << integral_part << std::endl;
std::cout << fractional_part << std::endl;
}
std::cout << std::endl;
// 負の浮動小数点数を、整数部と小数部に分解する
{
float x = -1.23f;
float integral_part = 0;
float fractional_part = std::modf(x, &integral_part);
std::cout << integral_part << std::endl;
std::cout << fractional_part << std::endl;
}
}- std::modf[color ff0000]
1
0.23
-1
-0.23
- 特定の環境では、早期に
constexpr対応されている場合がある:- GCC 4.6.1 以上
- GCC、Clang では、C++11 で追加された整数型オーバーロードは存在しない。
namespace std {
float modf(float value, float* iptr)
{
int save_round = fegetround();
fesetround(FE_TOWARDZERO);
*iptr = nearbyint(value);
fesetround(save_round);
return copysign(isinf(value) ? 0.0F : value - (*iptr), value);
}
double modf(double value, double* iptr)
{
int save_round = fegetround();
fesetround(FE_TOWARDZERO);
*iptr = nearbyint(value);
fesetround(save_round);
return copysign(isinf(value) ? 0.0 : value - (*iptr), value);
}
long double modf(long double value, long double* iptr)
{
int save_round = fegetround();
fesetround(FE_TOWARDZERO);
*iptr = nearbyint(value);
fesetround(save_round);
return copysign(isinf(value) ? 0.0L : value - (*iptr), value);
}
#if __cplusplus >= 201103L
template<typename T>
typename enable_if<is_integral<T>::value, double>::type
modf(T value, double* iptr)
{
return modf(static_cast<double>(value), iptr);
}
#endif
#if __cplusplus > 201402L
float modff(float value, float* iptr)
{
return modf(value, iptr);
}
long double modfl(long double value, long double* iptr)
{
return modf(value, iptr);
}
#endif
}- nearbyint[link nearbyint.md]
- copysign[link copysign.md]
- isinf[link isinf.md]
- fegetround[link ../cfenv/fegetround.md]
- fesetround[link ../cfenv/fesetround.md]
- FE_TOWARDZERO[link ../cfenv/fe_towardzero.md]
- enable_if[link ../type_traits/enable_if.md]
- is_integral[link ../type_traits/is_integral.md]
- P0533R9 constexpr for
<cmath>and<cstdlib>- C++23での、一部関数の
constexpr対応
- C++23での、一部関数の
- P1467R9 Extended floating-point types and standard names
- C++23で導入された拡張浮動小数点数型への対応として、
float、double、long doubleのオーバーロードをfloating-point-typeのオーバーロードに統合し、拡張浮動小数点数型も扱えるようにした
- C++23で導入された拡張浮動小数点数型への対応として、