- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我怎样才能便携地找出 INT_MAX
和 abs(INT_MIN
) 中的最小值? (这是 INT_MIN
的数学绝对值,而不是对 abs
函数的调用。)
它应该与大多数系统中的 INT_MAX
相同,但我正在寻找一种更便携的方式。
最佳答案
而典型值为INT_MIN
为-2147483648,典型值为INT_MAX
是2147483647,标准不保证。 TL;DR:您要搜索的值是 INT_MAX
在符合要求的实现中。但是计算 min(INT_MAX, abs(INT_MIN))
不便携。
INT_MIN
的可能值和 INT_MAX
INT_MIN
和 INT_MAX
由附件 E(实现限制)1 定义(C 标准,C++ 继承了这些东西):
The contents of the header are given below, in alphabetical order. The minimum magnitudes shown shall be replaced by implementation-defined magnitudes with the same sign. The values shall all be constant expressions suitable for use in #if preprocessing directives. The components are described further in 5.2.4.2.1.
[...]
#define INT_MAX +32767
#define INT_MIN -32767
[...]
标准要求类型为 int
为整数类型,可以表示 [INT_MIN, INT_MAX]
范围(第 5.2.4.2.1 节)。
然后,6.2.6.2。 (整数类型,也是 C 标准的一部分)开始发挥作用,并将其进一步限制为我们所知道的 二或一的补码:
For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; signed char shall not have any padding bits. There shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M ≤ N). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the following ways:
— the corresponding value with sign bit 0 is negated (sign and magnitude);
— the sign bit has the value −(2M) (two’s complement);
— the sign bit has the value −(2M − 1) (ones’ complement).
第 6.2.6.2 节。将有符号整数类型的值表示与其无符号兄弟的值表示联系起来也非常重要。
这意味着,你要么得到范围 [-(2^n - 1), (2^n - 1)]
或 [-2^n, (2^n - 1)]
, 其中 n
通常是 15 或 31。
现在来说第二件事:对有符号整数类型的操作,导致值不在 [INT_MIN, INT_MAX]
范围内,行为未定义。这是第 5/4 段在 C++ 中明确规定的:
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
对于 C,6.5/5 提供了一个非常相似的段落:
If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.
如果 INT_MIN
的值会发生什么?恰好小于 INT_MAX
的负数(例如分别为 -32768 和 32767)?计算 -(INT_MIN)
将是未定义的,与 INT_MAX + 1
相同.
因此,我们需要避免计算可能不在 [INT_MIN, INT_MAX]
范围内的值。 .幸运,INT_MAX + INT_MIN
始终在该范围内,如 INT_MAX
是一个严格的正值,INT_MIN
一个严格的负值。因此INT_MIN < INT_MAX + INT_MIN < INT_MAX
.
现在我们可以检查是否 INT_MAX + INT_MIN
等于、小于或大于 0。
`INT_MAX + INT_MIN` | value of -INT_MIN | value of -INT_MAX
------------------------------------------------------------------
< 0 | undefined | -INT_MAX
= 0 | INT_MAX = -INT_MIN | -INT_MAX = INT_MIN
> 0 | cannot occur according to 6.2.6.2. of the C standard
因此,确定 INT_MAX
的最小值和 -INT_MIN
(在数学意义上),下面的代码就足够了:
if ( INT_MAX + INT_MIN == 0 )
{
return INT_MAX; // or -INT_MIN, it doesn't matter
}
else if ( INT_MAX + INT_MIN < 0 )
{
return INT_MAX; // INT_MAX is smaller, -INT_MIN cannot be represented.
}
else // ( INT_MAX + INT_MIN > 0 )
{
return -INT_MIN; // -INT_MIN is actually smaller than INT_MAX, may not occur in a conforming implementation.
}
或者,为了简化:
return (INT_MAX + INT_MIN <= 0) ? INT_MAX : -INT_MIN;
只有在必要时才会评估三元运算符中的值。因此,-INT_MIN
要么未计算(因此不能产生 UB),要么是一个明确定义的值。
或者,如果你想要一个断言:
assert(INT_MAX + INT_MIN <= 0);
return INT_MAX;
或者,如果你想在编译时这样做:
static_assert(INT_MAX + INT_MIN <= 0, "non-conforming implementation");
return INT_MAX;
如果您对安全整数运算感兴趣,请查看我的 implementation of safe integer operations .如果您想查看操作失败和成功的模式(而不是冗长的文本输出),请选择 this demo .
根据架构的不同,可能还有其他选项来保证正确性,比如gcc的选项-ftrapv
.
关于c++ - 如何便携地找出 min(INT_MAX, and(INT_MIN))?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29808397/
我仍然没有找到为什么最低的带符号负数没有等效的带符号正数的原因?为了简单起见,我的意思是 3 位二进制数100 是-4?但我们不能有符号格式的正 4,因为我们不能。它溢出了。那么我们如何知道补码 10
我仍然没有找到为什么最低的有符号负数没有等效的有符号正数的原因?为简单起见,我的意思是 3 位二进制数100是-4?但是我们不能有正数 4 的签名格式,因为我们不能。它溢出了。那么我们如何知道二进制补
我正在解决一个关于二维数组的hackerrank问题,这是一个沙漏程序,我们必须找到每个沙漏的总和,然后打印最大的沙漏总和。代码如下 int hourglassSum(vector> arr) {
我希望 -2147483648 能够放入 4 个字节,因为它是使用 2 的补码表示的。 我错过了什么吗? INT MIN: -2147483648 INT MAX: 2147483647 sizeof
如果我有这样的事情怎么办: int a = 20; int min = INT_MIN; if(-a - min) //do something 如果正数大于 INT_MAX,则假设 INT_MIN。
这个问题在这里已经有了答案: Correct way to take absolute value of INT_MIN (5 个答案) Why the absolute value of the
我想在无符号中执行一些算术运算,需要取负整数的绝对值,比如 do_some_arithmetic_in_unsigned_mode(int some_signed_value) { unsign
我很困惑为什么结果被转换为 INT_MIN 而不是整数溢出? 有任何想法吗? #include int ft_atoi(const char *str) { int sign; in
谁能解释 GCC-7 编译器的以下行为? // main.cpp #include using namespace std; int main() { int a = -2147483648
gcc 为以下代码生成引发 SIGFPE 的 float 代码: #include int x = -1; int main() { return INT_MIN % x; } 但是,我在标
假设我有一个来自外部源的变量 i: int i = get_i(); 假设 i 是 INT_MIN 和二进制补码表示,-i 是未定义的吗? 最佳答案 这取决于平台。 C 支持三种负数表示法(参见 C9
嗯,我觉得我的问题比其他问题更复杂一些。我在尝试解决这个问题时意识到了这一点。 我尝试使用 int number = rand() % (INT_MAX - INT_MIN + 1) + INT_MI
我要解决的问题是: Implement pow(x, n), which calculates x raised to the power n (Leetcode problem 50) 我有以下代码
我需要你的一些智慧: 为什么不能这样做: std::vector min(INT_MIN, 3); “C++ 异常:内存位置 0x0000009AA63CF0A0 处的 std::length_err
这个问题在这里已经有了答案: for every int x: x+1 > x .... is this always true? (4 个答案) 关闭 9 年前。 for (i = 0; i <=
我怎样才能便携地找出 INT_MAX 和 abs(INT_MIN) 中的最小值? (这是 INT_MIN 的数学绝对值,而不是对 abs 函数的调用。) 它应该与大多数系统中的 INT_MAX 相同,
有符号整数在 x86 上通过二进制补码表示,其中符号位的值为 -(2^N)。这会产生 -2^N 和 2^N - 1 之间的典型可表示值范围(例如 -32768 到 32767)。 我很好奇,如果我将系
我正在尝试实现一个简单的程序来递归计算数字的幂。代码测试超过 INT_MAX 或 INT_MIN 的值,并且应该分配 power = -1。然而,即使经过一定数量的递归调用,当结果变量超过最大值时,它
我目前正在 www.udemy.com 上 C++ 类(class)在其中一节课中,老师正在使用 #include 演示一个整数可以拥有的最大整数个数。但是,当我去包括限制时,一切顺利,直到我尝试打印
signed long long value = -2147483648; cout << ((signed long long)value); 输出 2147483648(没有减号),为什么
我是一名优秀的程序员,十分优秀!