K
Ich hätte jetzt mal das.
wobei ich nicht weiss wie man die requirements auf template paramters legt, daher habe ich diese nur als Kommentar dazu geschrieben.
template<typename InT, typename OutT>
// requires std::is_integral<OutT>::value
// requires is_floating_point<InT>::value
inline
OutT losslessConvert1 (InT in)
{
InT converted = std::trunc (in);
if(in - converted != 0.0)
throw std::out_of_range("nein!") ;
using limit = std::numeric_limits<OutT> ;
if (converted < limit::min() || converted > limit::max())
throw std::out_of_range("nein, aber fast!") ;
return static_cast<OutT>(converted);
}
template<typename InT, typename OutT>
// requires std::is_integral<OutT>::value
// requires is_floating_point<InT>::value
inline
OutT losslessConvert2 (InT in)
{
InT converted{0.0};
InT fraction = std::modf (in, &converted) ;
if(fraction != 0.0)
throw std::out_of_range("nein!") ;
using limit = std::numeric_limits<OutT> ;
if (converted < limit::min() || converted > limit::max())
throw std::out_of_range("nein, aber fast!") ;
return static_cast<OutT>(converted);
}
die Exception wenn es nicht geht ist gewollt, wird aber wohl einen besseren Text bekommen.
wenn das so stimmt müsste ich nur noch rausfinden welche Version die schnellere ist.
das "Test" Programm
int main()
{
try {
std::cout << losslessConvert1<double, int>(1.0) << std::endl ;
} catch (const std::exception& e) {
std::cout << "Error: " << e.what () << std::endl ;
}
try {
std::cout << losslessConvert1<double, int>(1.00001) << std::endl ;
} catch (const std::exception& e) {
std::cout << "Error: " << e.what () << std::endl ;
}
try {
std::cout << losslessConvert1<double, int16_t>(300.00) << std::endl ;
} catch (const std::exception& e) {
std::cout << "Error: " << e.what () << std::endl ;
}
try {
std::cout << losslessConvert1<double, int8_t>(300.00) << std::endl ;
} catch (const std::exception& e) {
std::cout << "Error: " << e.what () << std::endl ;
}
try {
std::cout << losslessConvert2<double, int>(1.0) << std::endl ;
} catch (const std::exception& e) {
std::cout << "Error: " << e.what () << std::endl ;
}
try {
std::cout << losslessConvert2<double, int>(1.00001) << std::endl ;
} catch (const std::exception& e) {
std::cout << "Error: " << e.what () << std::endl ;
}
try {
std::cout << losslessConvert2<double, int16_t>(300.00) << std::endl ;
} catch (const std::exception& e) {
std::cout << "Error: " << e.what () << std::endl ;
}
try {
std::cout << losslessConvert2<double, int8_t>(300.00) << std::endl ;
} catch (const std::exception& e) {
std::cout << "Error: " << e.what () << std::endl ;
}
}
produziert
1
Error: nein!
300
Error: nein, aber fast!
1
Error: nein!
300
Error: nein, aber fast!