- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想为签名为 INT 的不同整数类型编写一系列函数
INT safe_product(INT a, INT b, bool& error);
它接受两个整数 a 和 b,如果 a * b 没有溢出则返回 a * b,如果 a * b 溢出则返回 0 并将错误设置为真。我也希望这个功能高效,我希望它在 32 位和 64 位平台上运行。
我正在考虑使用 std::int32_t
、std::uint32_t
、std::int64_t
、std 重载 safe_product::uint64_t
等。我相信 std::int64_t
并不总是用 32 位编译器定义的。有没有办法在编译时知道它是否被定义?
此外,如果我们在 64 位平台上,在 2 个 32 位整数之间实现安全乘积的最佳方法如下:
std::int32_t safe_product(std::int32_t a, std::int32_t b,
bool& error) {
const std::int64_t a_64 = a;
const std::int64_t b_64 = b;
const std::int64_t ab_64 = a_64 * b_64;
if (ab_64 > std::numeric_limits<std::int32_t>::max() ||
ab_64 < std::numeric_limits<std::int32_t>::min()) {
error = true;
return 0;
} else {
error = false;
return static_cast<std::int32_t>(ab_64);
}
}
但如果我们是 32 位平台,最快的算法可能意味着计算一些整数除法。
所以我有两个问题:
我如何声明我的 safe_product
,以便为我的平台上可用的所有整数类型定义它(显然不是为那些不存在的整数类型)?
如何使用我知道的算法使其在 32 位和 64 位上都高效?
最佳答案
以完全可移植的方式推导出最快的整数类型并不是一项简单的任务。您可能会考虑使用 int_fastXX_t
系列类型,但不能保证它们就是您想要的。您还可以查看 void*
的大小,并引入您自己的逻辑来推导您要使用的整数类型。为简单起见,我将 int
和 unsigned int
定义为最快的整数。
首先,定义我们的“最快”整数类型和一个辅助特征,以了解类型是否小到可以提升。正如您在示例中所做的那样,任何更小的东西都会被提升为“最快”的整数类型。任何大小相等或更大的东西都将使用整数除法来预测溢出。
#include <cstdint>
#include <limits>
#include <type_traits>
// Define the fastest types for our case
using t_fast_int = int;
using t_fast_uint = unsigned int;
// Helper trait, to indicate if a type is small enough to promote
template<class T>
struct t_is_small : std::bool_constant<sizeof(T) < sizeof(t_fast_int)> {};
其次,定义一个泛型函数并使用enable_if
([link( http://en.cppreference.com/w/cpp/types/enable_if )) 只为小类型启用它。这使用您在问题中描述的方法。
template<class T>
std::enable_if_t<t_is_small<T>::value, T>
safe_product(T a, T b, bool& error)
{
// Should we use intmax_t or uintmax_t in this case?
using t_large = std::conditional_t<std::is_signed<T>::value, t_fast_int, t_fast_uint>;
const t_large a_64 = a;
const t_large b_64 = b;
const t_large ab_64 = a_64 * b_64;
if (ab_64 > std::numeric_limits<T>::max() ||
ab_64 < std::numeric_limits<T>::min())
{
error = true;
return 0;
}
else
{
error = false;
return static_cast<T>(ab_64);
}
}
最后,为大整数类型添加另一个重载。请注意,enable_if
条件已反转。我使用整数除法来预测上溢或下溢。
template<class T>
std::enable_if_t<t_is_small<T>::value == false, T>
safe_product(T a, T b, bool& error)
{
if(b == 0) {
// The result will be zero (avoids division by zero below)
error = false;
}
else {
// Calculate the largest `a` that would not result in an overflow
constexpr auto max_int = std::numeric_limits<T>::max();
auto max_a = max_int / b;
// Calculate the smallest `a` that would not result in underflow
constexpr auto min_int = std::numeric_limits<T>::min();
auto min_a = min_int / b;
// If a is greater than max_a an overflow would occur
// If a is less than min_a an undeflow would occur
if(b > 0) {
error = (a > max_a) || (a < min_a);
}
else {
error = (a < max_a) || (a > min_a);
}
}
if(error) {
return 0;
}
else {
return a * b;
}
}
关于c++ - 为平台上可用的所有整数定义一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41891582/
我正在尝试学习 Fortran,并且看到了很多不同的定义,我想知道他们是否正在尝试完成同样的事情。以下有什么区别? 整数*4 整数(4) 整数(kind=4) 最佳答案 在 Fortran >=90
我以前从未编程过,最近(1 周前)才开始学习!第一门类(class)是函数式编程,使用 Haskell。 我有一项学校作业,我想通过删除一两个步骤来改进它,但我遇到了一个讨厌的错误。 基本上,我创建了
给定以下GraphQL请求和变量: 请求: query accounts($filter:AccountFilter, $first_:String, $skip_:Int) { accounts
我已经搜索了 StackOverflow,但找不到关于如何检查计算器应用程序的数字输入正则表达式的答案,该计算器应用程序将检查每个 keyup 的以下格式(jquery key up): 任何整数,例
类似于我上一篇致歉的文章,但没有那么长篇大论。基本上我想知道当每次重绘调用只重绘屏幕的一小部分时,优化重绘到 JFrame/JPanel 的最佳选择是什么。 此外,除了重绘重载之外,我并不是 100%
所以在我的教科书中有一个使用 f# 的递归函数的例子 let rec gcd = function | (0,n) -> n | (m,n) -> gcd(n % m,m);; 使用此功能,我的教科书
我有一个数据结构,例如表达式树或图形。我想添加一些“测量”功能,例如depth和 size . 如何最好地键入这些函数? 我认为以下三个变体的用处大致相同: depth :: Expr -> Int
这样写比较好 int primitive1 = 3, primitive2 = 4; Integer a = new Integer(primitive1); Integer b = new Inte
我是 Java 8 新手,想根据键对 Map 进行排序,然后在值内对每个列表进行排序。 我试图寻找一种 Java 8 方法来对键和值进行排序。HashMap>映射 map.entrySet().str
这就是我的目标... vector ,int> > var_name (x, pair (y),int>); 其中 x 是 vector var_name 的大小,y 是对内 vector 的大小。
这里是 an answer to "How do I instantiate a Queue object in java?" , Queue is an interface. You can't i
这个问题在这里已经有了答案: Weird Integer boxing in Java (12 个答案) Why are autoboxed Integers and .getClass() val
我们可以使用 C++ STL 做这样的事情吗?如果是,我将如何初始化元素?我试图这样做,但没有成功。 pair,vector>p; p.first[0]=2; 最佳答案 Can we do som
您好,我正在尝试为百分比和整数数组中的数字找到索引。假设 arraynum = ['10%','250','20%','500'] 并且用户发送一个值 15%,这个数字在哪个范围内居住?我可以使用这段
我与三列有关系:ProductName、CategoryID 和 Price。我需要选择仅那些价格高于给定类别中平均产品价格的产品。(例如,当apple(ProductName)是fruit(Cate
我已经坚持了一段时间,我正在尝试将一些数据配对在一起。这是我的代码。 #include #include using namespace std; int main() { pair data(
我收到错误:'(Int, Int)' 与 'CGPoint' 不相同 如何将 (Int, Int) 转换为 CGPoint let zigzag = [(100,100), (100,150)
我在 .cpp 文件中发现了以下代码。我不理解涉及头文件的构造或语法。我确实认识到这些特定的头文件与 Android NDK 相关。但是,我认为这个问题是关于 C++ 语法的一般问题。这些在某种程度上
我将这些输入到 Scala 解释器中: val a : Integer = 1; val b : Integer = a + 1; 我收到消息: :5: error: type mismatch;
C++:vector>v(size);当我试图打印出值时显示 0 作为值,但是当未声明 vector 大小时它显示正确的输出?为什么这样?例如: int x; cin>>x; vector>v(x);
我是一名优秀的程序员,十分优秀!