c++ - -9'223'372'036'854'775'808LL 无符号
问题描述
由于 C++20 二进制补码表示是标准允许的唯一表示,保证范围从 -2 N-1到 +2 N-1 -1。因此,对于 64 位有符号整数类型,范围从-9'223'372'036'854'775'808
到9'223'372'036'854'775'807
。但是,此代码不能在 Visual Studio 上编译(也不能在 gcc 上编译)
int main()
{
long long x{-9'223'372'036'854'775'808LL};
// error C4146: unary minus operator applied to unsigned type, result still unsigned
// error C2397: conversion from 'unsigned __int64' to '__int64' requires a narrowing conversion
}
然而,如果我用 compiles 替换代码long long x{-9'223'372'036'854'775'807LL - 1}
就好了并且x
保持正确的值。我没有得到什么?
解决方案
如果没有LL
后缀,则该类型将被视为符合标准的列表中的第一个类型。如果您使用LL
后缀,则该值将特别具有 type long long
。然而,任何一种方式9'223'372'036'854'775'808
都太大而无法适应 along long
(这是最大的有符号类型),因此一些编译器允许它作为扩展成为unsigned long long
,因此会发出警告。在这种情况下, GCC 和 Clang实际上会发出警告。与许多人的看法相反,C 或 C++ 中没有负整数文字。-9'223'372'036'854'775'808
是应用于整数的一元减号9'223'372'036'854'775'808
字面量的类型
整数文字的类型是值可以适合的第一种类型,来自类型列表,这取决于使用了哪个数字基数和哪个整数后缀。
- 无后缀
- 十进制基数:
- 整数
- 长整数
- long long int (C++11 起)
- 二进制、八进制或十六进制基数:
- 整数
- 无符号整数
- 长整数
- 无符号长整数
- long long int (C++11 起)
- unsigned long long int (C++11 起)
- ...
- 后缀:ll 或 LL
- 十进制基数:
- long long int (C++11 起)
- 二进制、八进制或十六进制基数
- 长长整数
- unsigned long long int (C++11 起)
- ...
如果整数字面量的值太大而无法容纳后缀/基数组合所允许的任何类型,并且编译器支持扩展整数类型(例如
__int128
),则可以给字面量赋予扩展整数类型——否则程序会出错-形成。
事实上,过去有很多类似的问题 where-2147483648
也是 unsigned因为long long
当时不在 C 和 C++ 标准中,最大的类型是unsigned long
:
推荐阅读
- javascript - Unable to select alert message in SVG format in Chrome browser
- snowflake-cloud-data-platform - 部署存储过程时使用会话变量-雪花
- regex - 在保留换行符的同时修剪字符串
- python - 有没有办法在 python 中浮动文件中的每一行,然后将这些行存储为变量?
- javascript - 视频定位问题 HTML mobile
- java - 访问公共字段如何与继承一起工作?
- for-loop - 将数字存储在具有范围的列表中
- python - 有换行符时 textwrap.dedent 不起作用
- c# - “包含”不起作用,控制器 asp.net
- python - 在 Pandas 上安装 Pip 失败?