我正在寻找一个标准库或Boost函数,可以无损地将一个数字转换为另一个原始类型,并以某种方式通知我演员是否无损(或者如果不是则抛出异常)。以下是一些例子:
auto x = lossless_cast<double>(1u); // ok, double can represent 1
auto x = lossless_cast<int>(1.2); // fail, int can't represent 1.2
auto x = lossless_cast<int>(1E200); // fail, int can't represent 1E200
boost::numeric_cast
接近它会拾取掉落在目标类型的数值范围之外的强制转换,但如果它们是无损的但在目标类型中则不会(请参阅我的第二个例子)。
有一个SO question for the C language which provides some hand-rolled solutions to this problem,但我正在使用boost
或标准库解决方案,基本上具有以下功能:
template <typename out, typename in>
out lossless_cast(in in_value)
{
out out_value = static_cast<out>(in_value);
if (static_cast<in>(out_value) != in_value)
throw; // some exception
return out_value;
}
此功能是否存在?
答案 0 :(得分:3)
我很确定标准中没有任何预先提出的内容,并且没有任何关于提升的内容,但它是一个很大的库。使用强制转换的任何实现都必须小心每个4.9 [conv.fpint]的超出范围值的未定义行为,但是当boost::numeric_cast<>
表面上处理它时,您可以使用:< / p>
template <typename U, typename T>
inline U is_lossless(T t)
{
U u = boost::numeric_cast<U>(t);
T t2 = boost::numeric_cast<T>(u); // throw if now out-of-range
if (t != t2)
throw whatever-you-like;
return u;
}
恢复numeric_cast<>
时t2
的需求最不明显:它确保u
仍然在范围内,因为从int64_t x
到double y
的值可以y
要成功,但要使int64_t
中的整数值与double
的超出范围的近似值进行近似,以便从boost::numeric_cast<>
退回时具有未定义的行为。
上述合法性/稳健性要求def add(mytweets):
author = input("\nWhat is your name? ")
while True:
text = input("what would you like to tweet? ")
if len(text) > 140:
print("\nTweets can only be 140 characters!")
continue
else:
break
entry = Tweet.Tweet(author, text)
print("\nYour tweet has been saved!")
正确避免未定义的行为,我尚未验证。