标签: integer-overflow

C++过早地溢出了

我对C++有一个奇怪的问题,其中长数据类型在它应该之前很久就会溢出.我正在做的事情(到目前为止成功)是使整数表现得像浮点数,因此范围[-32767,32767]被映射到[-1.0,1.0].它失败的地方是更大的参数表示大于1.0的浮点数:

inline long times(long a, long b) {
  printf("a=%ld b=%ld ",a,b);
  a *= b;
  printf("a*b=%ld ",a);
  a /= 32767l;
  printf("a*b/32767=%ld\n",a);
  return a;
}

int main(void) {
  printf("%ld\n",times(98301l,32767l));
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

a=98301 b=32767 a*b=-1073938429 a*b/32767=-32775
-32775
Run Code Online (Sandbox Code Playgroud)

所以时代(98301,32767)类似于3.0*1.0.当时间参数小于32767(1.0)时,此代码可以正常工作,但上述参数的中间步骤都不会溢出64位长.

有任何想法吗?

c++ overflow integer-overflow

7
推荐指数
1
解决办法
357
查看次数

我能用valgrind检测整数溢出缺陷吗?

我能用valgrind检测整数溢出缺陷吗?它中的哪个工具可以做到这一点?

valgrind integer-overflow

6
推荐指数
1
解决办法
897
查看次数

如何在 PowerShell 中抑制溢出检查?

PowerShell 似乎在算术运算和转换后执行边界检查。例如,以下操作失败:

[byte]$a = 255
$a++

$a = [byte]256
Run Code Online (Sandbox Code Playgroud)

有没有办法强制溢出或类型转换,而无需通过模或 C# 和 Add-Type 进行手动计算?

powershell integer-overflow unchecked unchecked-conversion

6
推荐指数
2
解决办法
1270
查看次数

如果我要对32位以上的对象进行更多的引用,会发生什么?

所以我刚刚学会了声明Object类型的变量(即Object a;)时,为该变量分配了32位空间.在这个变量/引用中,有一个实际Object的内存地址.

现在让我们假装我有足够的内存来做这件事.

如果我创建了超过4,294,967,296(2 32)个Object类型的变量并尝试将它们分配给不同的对象会发生什么?由于整数溢出,某些变量/引用是否会获得相同的内存地址?这意味着在内存中引用超过4,294,967,296个对象是不可能的?

java memory-management reference integer-overflow

6
推荐指数
1
解决办法
210
查看次数

C 标准是否对 INT_MIN 和 INT_MAX 之间的关系做出保证?

例如,在 2 和 1 的补码中,INT_MAX*-1 都是有效数字。这有保证吗?还有其他保证吗?例如,在任何架构上 INT_MIN 可以是 -1 或 0 吗?关于 (INT_MAX + INT_MIN) 我们能知道什么吗?我们甚至可以知道 (INT_MAX + INT_MIN) 不会导致未定义的行为吗?

c standards signed integer-overflow

6
推荐指数
1
解决办法
234
查看次数

Swift:如何禁用函数的整数上溢/下溢陷阱

我正在将一些旧的C代码导入到一个快速项目中,并将其移植到纯粹的快速代码中.

其中一些做"加密",其中它做了类似的事情

let a = UInt8(x) // e.g. 30
let b = a - 237
Run Code Online (Sandbox Code Playgroud)

在C中,这只是下溢和环绕,这对于这个特定的功能来说很好.

在swift中,这会触发fatalError并使用EXC_BAD_INSTRUCTION终止我的程序,因为默认情况下swift用于捕获整数上溢/下溢.

我知道我可以通过使用-Ofast进行编译来在整个项目级别关闭此检查,但我真的想关闭这一行代码的溢出检查(或者可能只是特定的函数本身).

注意:我特别想保留C函数的行为,而不仅仅是将事物提升到Int32或Int64

这个特殊的术语似乎很难谷歌.


更新:答案是溢出运算符,它们是

  • &- 减法
  • &+ 另外
  • &* 为了倍增

我在之前的搜索中找不到它们.哎呀

integer-overflow swift

6
推荐指数
2
解决办法
1686
查看次数

去打印大量

我目前正在做 Go Lang 教程,准确地说是“数值常量”。示例代码以以下语句开头:

const (
    // Create a huge number by shifting a 1 bit left 100 places.
    // In other words, the binary number that is 1 followed by 100 zeroes.
    Big = 1 << 100
    // Shift it right again 99 places, so we end up with 1<<1, or 2.
    Small = Big >> 99
)
Run Code Online (Sandbox Code Playgroud)

常量Big显然很大,我正在尝试打印它及其类型,如下所示:

fmt.Printf("%T", Big)
fmt.Println(Big)
Run Code Online (Sandbox Code Playgroud)

但是,我对这两行都收到以下错误:

# 命令行参数 ./compile26.go:19: 常量 1267650600228229401496703205376 溢出 int

我会尝试将 Big 转换为其他类型,例如uint64,它溢出了相同的错误,或者只是将其转换为字符串,但是在尝试时Big.String()出现以下错误: …

integer-overflow biginteger go

6
推荐指数
1
解决办法
1843
查看次数

有符号整数溢出:999999999 * 10 无法用“int”类型表示错误

为什么会出现运行时错误?我做了range2很长很长。

代码:

/*VARIABLES FOR WHILE LOOP*/
 long long range1 = 9;
 int length = 1;

 /*FIND NUM'S LENGTH*/
 while (NUM > range1)     
 {
    long long range2 = range1 * 10 + 9;
    length += 1;
 }
Run Code Online (Sandbox Code Playgroud)

错误:

Credit.c:25:25:运行时错误:有符号整数溢出:999999999 * 10 无法以“int”类型表示

c integer-overflow cs50

6
推荐指数
1
解决办法
5万
查看次数

如何在C中实现包装signed int加法

这是对问题的完全重写。希望现在更清楚了。

我想在 C 中实现一个函数,该函数signed int在溢出的情况下执行带包装的s相加。

我想主要针对 x86-64 架构,但当然实现越便携越好。我还主要关心通过 gcc、clang、icc 以及 Windows 上使用的任何东西生成体面的汇编代码。

目标是双重的:

  1. 编写不落入未定义行为黑洞的正确 C 代码;
  2. 编写被编译为体面的机器代码的代码。

体面的机器代码是指在本机支持该操作的机器上的单个leal或单个addl指令。

我能够满足这两个要求中的任何一个,但不能同时满足。

尝试 1

想到的第一个实现是

int add_wrap(int x, int y) {
    return (unsigned) x + (unsigned) y;
}
Run Code Online (Sandbox Code Playgroud)

这似乎适用于gcc、clang和 icc。但是,据我所知,C 标准没有指定从unsigned intto的强制转换signed int,为实现留下了自由(另请参见此处)。

否则,如果新类型是有符号的并且值不能在其中表示;要么结果是实现定义的,要么引发实现定义的信号。

我相信大多数(全部?)主要编译器都会从unsignedto进行预期的转换int,这意味着它们采用正确的代表性模数 2^N,其中 N 是位数,但标准并未强制要求,因此不能依赖(愚蠢的 C 标准再次命中)。此外,虽然这是在二进制补码机上做的最简单的事情,但在补码机上是不可能的,因为有一个类是不可表示的:2^(N/2)。

尝试 2

根据clang docs,可以__builtin_add_overflow像这样使用

int add_wrap(int x, int …
Run Code Online (Sandbox Code Playgroud)

c integer integer-overflow

6
推荐指数
1
解决办法
352
查看次数

溢出和隐式转换之间有什么区别,无论是技术级别还是位级别(cpu-寄存器级别)?

(我是新手,所以说的可能有不准确的地方)

\n

在我当前的思维模型中,溢出是一种算术现象(当我们执行算术运算时发生),而隐式转换是一种赋值(初始化与否)现象(当我们对右手的值不进行赋值时发生)适合左侧值。

\n

然而,我经常看到“溢出”和“隐式转换”这两个概念可以互换使用,与我的预期不同。例如,来自 learncpp 团队的这段引用,谈论了有符号 int 的溢出和“位不足”:

\n
\n

当我们尝试存储超出类型范围的值时,就会发生整数溢出(通常简称为溢出)。本质上,我们试图存储的数字需要比对象可用的位数更多的位数来表示。在这种情况下,数据会丢失,因为对象没有足够的内存来存储所有内容[1]。

\n
\n

这是关于 unsigned int 的溢出:

\n
\n

如果我们尝试将数字 280(需要 9 位来表示)存储在 1 字节(8 位)无符号整数中,会发生什么情况?答案是溢出 [2]*

\n
\n

尤其是这个,他使用“模换行”:

\n
\n

这里\xe2\x80\x99是思考同一件事的另一种方式。任何大于该类型可表示的最大数字的数字都简单地 \xe2\x80\x9c 包裹 \xe2\x80\x9d (有时称为 \xe2\x80\x9cmodulo 包裹 \xe2\x80\x9d)。255 在 1 字节整数范围内,因此 255 就可以了。然而,256 超出了范围,因此它回绕到值 0。257 回绕到值 1。280 回绕到值 24 [2]。

\n
\n

在这种情况下,据说超出左手限制的赋值会导致溢出,但我希望在这种情况下使用术语“隐式转换”。

\n

我看到术语“溢出”也用于其结果超出左侧限制的算术表达式。

\n
\n

1 隐式转换和上溢/下溢之间有技术上的区别吗?

\n

我想是这样。在参考文献 [3] 的“数值转换 - 积分转换”部分中,对于无符号整数:

\n
\n

[...] 结果值是等于源值模 2^n\n 的最小无符号值,其中 n 是用于表示目标类型的位数 [3]。

\n
\n

对于签名(粗体我的): …

c++ assembly integer-overflow language-lawyer implicit-conversion

6
推荐指数
1
解决办法
215
查看次数