问题标签 [integer-promotion]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 是在结果上还是在每个操作数上完成对 unsigned 的提升?
在以下情况下:
2147483647U > -2147483647 - 1
由于转换/提升为无符号,它将评估为 false。
我的问题是,它将如何推广?
是先进行减法运算,然后将结果提升为无符号,还是将每个操作数提升为无符号?
有符号的 4 位 [-8,7] 和无符号的 [0,15] 示例:
7U > -7 -1
这会变成 (unsigned)(-7) + (unsigned)(-1) = (9U) + (15U) = 24U
所以我们最终7U > 24U
是错误的。
或者我们会有
-7-1 = -8 = 8U
所以7U > 8U
这是错误的
c++ - 为什么这个函数调用不明确?
我正在阅读标准并试图弄清楚为什么如果没有演员表就无法解析这段代码。
它是这样说的:
4.13 整数转换秩[conv.rank]
每个整数类型都有一个整数转换等级,定义如下:
— 任何无符号整数类型的等级应等于相应有符号整数类型的等级。
— char 的等级应等于signed char 和unsigned char 的等级。
特别是,让我的 jimmies 沙沙作响的是,它没有说任何无符号整数类型,只是无符号字符。我的猜测是 char 通过转换被提升为无符号类型。这是真的?
c++ - C++ - uchar 按位不产生 int
当按位而不是无符号字符应用时,我对 C++ 的行为感到惊讶。
取二进制值01010101b
,即0x55
或85
。不按位应用八位表示应该产生10101010b
,即0xAA
,或170
。
但是,我无法在 C++ 中重现上述内容。以下简单断言失败。
我用下面的代码打印了0x55
、0xAA
和~0x55
(as uchar) 的值。它表明按位不做我期望它做的事情。
为 打印的数字~0x55
等于11111111111111111111111110101010b
,这是 32 位按位而不是0x55
。因此,~
即使我将输入显式转换为unsigned char
. 这是为什么?
我应用了另一个测试来查看~
运算符返回的类型。结果是int
在unsigned char
输入上:
产生以下编译器错误,这表明结果是int
.
我究竟做错了什么?0xAA
或者,我如何让 C++ 生成~0x55
?
完整代码在这里
c - unsigned int a = -1 的位表示
unsigned int x =-1;
Can we assign unsigned int with a negative integer的位表示形式是什么?
输出 :
相同的
怎么可能,x 是无符号的
输出:
真的
c - 当 C 表达式中发生整数溢出时会发生什么?
我有以下 C 代码:
这是替代实现:
第一个例子很明显,uint16_t
类型足够大以包含结果。当我在 OS/X 上使用编译器尝试第二个示例时clang
,它正确返回 true。那里会发生什么?是否有某种临时的、更大的类型来包含结果?
c++ - 编译器警告转换
我们正在使用-Wconversion
启用的 gcc 进行编译。当我离开isBitSet
下面函数返回的移位结果时,我收到以下警告。
警告:从“int”转换为“u_int16_t {aka short unsigned int}”可能会改变其值 [-Wconversion]
我尝试将 lambda 更改为以下,但仍然出现相同的错误。我该如何解决?
java - 为什么将整数添加到列表时没有提升
在 Java 中,我创建了一个 Double 的 ArrayList,并调用了方法 list.add(1),但是,我得到了一个错误。如果我可以将 int 分配给这样的 double 变量: double num = 1; 由于自动提升,那为什么我不能通过自动提升将 1 添加到 Double 的 ArrayList 中?
c - 整体提升/转换:我为什么要关心结果类型的名称?
我一直试图围绕整数提升的 C99 规则和整数类型的常用算术转换。在烧掉几个神经元之后,我得出了一套我自己的规则,这些规则要简单得多,但我相信,它相当于官方的:
更新:为了这个问题,我首先定义“物理类型”如下
定义:如果两个整数类型具有相同的大小和符号,则它们是相同的物理类型。
如果你认为这个定义有问题,那么你可能对问题 2 有一个很好的答案。
简化的促销/转换规则
类型排名:在T1和T2两种积分类型中,“最好”的是:
- 以较大者为准
- 如果它们具有相同的大小,以未签名者为准
- 如果它们具有相同的大小和符号,它们中的任何一个,因为它们在物理上是相同的。
积分提升:类型 T 的值应该提升为
提升(T) = 最佳(T, int)
整数类型的常用算术转换:在计算 T1 和 T2 类型的二元运算符之前,应将参数转换为合适的通用类型,即:
共同(T1,T2)=最佳(T1,T2,int)
警告:虽然我相信我的规则给出了正确的物理类型,但在单一类型具有不同名称的情况下,它们可能无法提供正确的类型名称。例如,在系统上int==long
,官方规则说
common(unsigned int, long) = unsigned long
而我的规则说它是unsigned int
(无论如何在物理上是相同的)。但这应该不是问题,因为名称并不重要。还是他们?
在这个漫长的前奏之后,真正的问题来了,它有两个方面:
问题1:我的规则正确吗?
我读了几遍官方的,但我仍然觉得它们令人困惑。因此,我可能误解了一些东西。如果我错了,请提供官方规则和我的规则产生不同类型的示例。我的意思是:不同的物理类型,而不仅仅是物理上相同的不同类型。
一个现实世界的例子将是首选。如果没有找到,如果假设的 C 环境的描述足够详细以令人信服(相关类型的大小等),那么理论上的示例就可以了。
如果我在这里是正确的,那么第二个问题就变得相关了。
问题 2:我为什么要关心提升/转换类型的名称?
如果我是正确的,那么显而易见的问题是“标准委员会的人为什么要编写如此复杂的规则?”。他们唯一的回答是我能想到的,他们不仅要指定促销/转换产生的物理类型,还要指定命名这些类型的正确方法。但是,他们为什么在乎呢?这些类型仅由编译器在内部使用,只要我们了解它们的物理性质,我们如何命名它们并不重要。这个推理有问题吗?您能想到这样一种情况,即 T1 和 T2 在物理上是相同的,但重要的是要知道事物是否会自动升级或转换为 T1 而不是 T2?同样,现实世界的示例将是首选,否则,如果足够详细,理论示例也可以。
基本原理
(部分添加于 2014-11-10,以解决一些评论)
在搜索这些主题时,我总是看到它们在算术运算符行为的上下文中进行讨论,更具体地说,是这些运算符返回的结果。例如,表达式-1L < 1U
是有问题的,因为它在 long 确实比 int 长的系统上为 true,否则为 false。我相信理解这类问题是一件好事,但需要一个复杂的规则集来做到这一点是一件坏事。因此,努力构建一个更简单的规则集,可靠地给出相同的结果。
我完全明白,我的规则对于任何发现真实规则足够简单的人来说都是无用的。我也理解并且恭敬地不同意那些表示依赖官方规则以外的任何东西本质上是不好的观点的人。不过,如果我的规则对除我以外的任何人都有帮助的话,它们还是会有用处的。
关于我个人的偏见:作为一名物理学家,我非常看重简单性。我习惯于处理那些不是——也不应该是——终极真理的理论,但它们被证明是非常有用的,只要你了解它们的适用范围,它们就可以安全使用。在任何给定的情况下,最好的理论都不是最完整的:它是仍然适用的最简单的理论。例如:我不会使用量子引力来计算单摆的周期。我在这里发布这个问题是为了就上述规则的适用范围获得专家意见。
到目前为止,我所拥有的是:
- varargs 案例(坦克,mafso),这似乎是 C99 中这些规则至少在原则上不适用的唯一情况
- 关键字(感谢 Pascal Cuoq) ,
_Generic
作为 C11 功能,稍微超出范围- C++11
auto
关键字,它进一步超出了范围,但有趣的是它会带来(否则不相关的)关于别名规则的担忧。
c - 有符号/无符号 int、short 和 char
我正在尝试了解以下代码的输出:http: //phrack.org/issues/60/10.html
在这里引用它以供参考:
我在我的机器上得到的输出是:-
这是我的理解:-
赋值 s=l, c=l 将导致 s 和 c 被提升为整数,它们将分别具有 l 的最后 16 位 (0xbeef) 和最后 8 位 (0xef)。
Printf 尝试将上述每个值(l、s 和 c)解释为无符号整数(因为 %x 作为格式说明符传递)。从输出中我看到符号扩展已经发生。我的疑问是,既然 %x 代表 unsigned int,为什么在打印 s 和 c 时会发生符号扩展?s 的输出不应该是 0x0000beef 而 c 的输出不应该是 0x000000ef 吗?
c++ - “通常的算术转换”和“整数提升”是一回事吗?
“通常的算术转换”和“整数提升”是一回事吗?我读过“通常的算术转换”用于使表达式的操作数具有相同的类型,而“整数提升”用于提升小于的类型int
to的类型int
,但在MSDN中,这两个概念都放在“通常算术转换”。