标签: integer-overflow

GCC内联汇编乘法

我正在尝试在Linux(x86)上学习GCC内联汇编,我的第一个实验是尝试实现乘法的整数溢出检测.这似乎很容易,但它有副作用,我不明白.

所以,在这里我想要将两个无符号8位整数相乘,并查看结果是否溢出.基本上我只是将第一个操作数加载到AL寄存器中,将另一个操作数加载到BL寄存器中,然后使用该mul指令.结果存储为AX寄存器中的16位值.所以我然后将AX寄存器中的值复制到我的C变量b,除非它溢出.如果它溢出我设置c为1.

 uint8_t a = 10;
 uint8_t b = 25;
 uint8_t c = 0; // carry flag

 __asm__
 (
  "clc;"                  // Clear carry flag
  "movb %3, %%al;"        // Load b into %al
  "movb %2, %%bl;"        // Load a into %bl 
  "mul %%bl;"             // Multiply a * b (result is stored in %ax)
  "movw %%ax, %0;"        // Load result into b
  "jnc out;"              // Jump to 'out' if the carry flag is not set
  "movb …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly integer-overflow inline-assembly

5
推荐指数
2
解决办法
2596
查看次数

永远增加,你得到-2147483648?

由于一个聪明而复杂的原因,我不想解释(因为它涉及以非常丑陋和hacky的方式制作计时器),我写了一些类似的C#代码:

int i = 0;
while (i >= 0) i++; //Should increment forever
Console.Write(i);
Run Code Online (Sandbox Code Playgroud)

我希望程序永远挂起或崩溃或者其他东西,但是,令我惊讶的是,在等待大约20秒左右之后,我得到了这个输出:

-2147483648
Run Code Online (Sandbox Code Playgroud)

编程已经教会了很多东西,但我仍然无法理解为什么不断增加一个数字导致它最终变成负面...这里发生了什么?

c# loops increment integer-overflow infinite-loop

5
推荐指数
2
解决办法
5758
查看次数

如何避免快速模幂运算中的溢出

我正在尝试解决一个关于 SPOJ 的问题,它需要模幂运算。我正在使用以下 C 代码

long long modpow(long long a,long long b,long long mod)
{
    long long product,pseq;
    product=1
    pseq=a%mod;
    while(b>0)
    {
        if(b&1)
            product=(product*pseq)%mod;
        pseq=(pseq*pseq)%mod;
        b>>=1
    }
    return product;
}
Run Code Online (Sandbox Code Playgroud)

问题是当我想计算时(2^249999999997)%999999999989,它会0因为溢出而给出答案。如何避免溢出?

c integer-overflow c99

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

在 Fortran 中捕获整数异常

有没有办法捕获整数异常,gfortran或者ifort像捕获浮点异常一样?

考虑这个简单的程序来计算阶乘:

program factorial
  use, intrinsic :: iso_fortran_env 

  implicit none
  integer(8)          :: fac
  real(REAL64)        :: facR
  integer,parameter   :: maxOrder = 30
  integer             :: i

  fac = 1 ; facR = 1.e0_REAL64
  do i=2,maxOrder
    fac=fac*i ; facR=facR*real(i,REAL64)
    write(*,*) i, fac, facR
  enddo ! i

end program
Run Code Online (Sandbox Code Playgroud)

在某些时候会出现溢出 -integer(8)如此处所示,它将发生在 21 左右。但是如果没有使用浮点数作为参考的计算,我无法确定......

fortran integer-overflow gfortran intel-fortran

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

Python在处理大浮点数和整数时防止溢出错误

我正在开发一个 python 程序来计算斐波那契数列中的数字。这是我的代码:

import math
def F(n):
    return ((1+math.sqrt(5))**n-(1-math.sqrt(5))**n)/(2**n*math.sqrt(5))
def fib(n):
    for i in range(n):
        print F(i)
Run Code Online (Sandbox Code Playgroud)

我的代码使用这个公式来查找斐波那契数列中的第 N 个数字:

在此处输入图片说明

这可以计算斐波那契数列中的许多数字,但我确实遇到了溢出错误。

如何改进此代码并防止溢出错误?

注意:我使用的是 python 2.7。

python optimization integer-overflow sequence fibonacci

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

绕过CBMC检测到的无符号加法溢出

CBMC在以下行中检测到可能的无符号加法溢出:

l = (t + *b)&(0xffffffffL);
c += (l < t);
Run Code Online (Sandbox Code Playgroud)

我同意第一行有可能出现溢出,但我正在处理CBMC无法查看的下一行的进位.如果有溢出,我设置进位1.所以,因为我知道这个,这就是我希望我的代码工作的方式,我想继续进行验证过程.那么,我怎么告诉CBMC忽略这个错误并继续前进呢?

c integer model-checking integer-overflow cbmc

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

在 Rust 中链接检查算术运算

在执行带有溢出检查的整数算术时,计算通常需要组合多个算术运算。在 Rust 中链接检查算术的一种直接方法是使用checked_*方法和Option链接:

fn calculate_size(elem_size: usize,
                  length: usize,
                  offset: usize)
                  -> Option<usize> {
    elem_size.checked_mul(length)
             .and_then(|acc| acc.checked_add(offset))
}
Run Code Online (Sandbox Code Playgroud)

但是,这告诉编译器为每个基本操作生成一个分支。我遇到了一种使用overflowing_*方法更展开的方法:

fn calculate_size(elem_size: usize,
                  length: usize,
                  offset: usize)
                  -> Option<usize> {
    let (acc, oflo1) = elem_size.overflowing_mul(length);
    let (acc, oflo2) = acc.overflowing_add(offset);
    if oflo1 | oflo2 {
        None
    } else {
        Some(acc)
    }
}
Run Code Online (Sandbox Code Playgroud)

不考虑溢出而继续计算并使用按位 OR 聚合溢出标志可确保在整个评估中最多执行一个分支(前提是overflowing_*生成无分支代码的实现)。这种优化友好的方法更麻烦,并且在处理中间值时需要谨慎。

有没有人有过 Rust 编译器如何在各种 CPU 架构上优化上述任一模式的经验,以判断显式展开是否值得,尤其是对于更复杂的表达式?

integer-overflow rust integer-arithmetic

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

在执行时上溢/下溢是否为未定义的行为?

我正在阅读有关未定义行为的内容,我不确定它是否只是一个编译时功能,或者它是否可以在执行时发生.

我很好理解这个例子(这是从维基百科的未定义行为页面中提取的):

C语言的一个例子:

int foo(unsigned x)
{
    int value = 5;
    value += x;
    if (value < 5)
        bar();
    return value;
}
Run Code Online (Sandbox Code Playgroud)

值x不能为负,并且由于有符号整数溢出是C中未定义的行为,编译器可以假设在if检查行value >= 5.因此编译器可以忽略if和调用该函数bar,因为if它没有副作用,并且它的条件永远不会被满足.因此,上面的代码在语义上等同于:

int foo(unsigned x)
{
     int value = 5;
     value += x;
     return value;
}
Run Code Online (Sandbox Code Playgroud)

但这发生在编译时.

如果我写,例如:

void foo(int x) {
    if (x + 150 < 5)
         bar();
}

int main() {
    int x;
    std::cin >> x;
    foo(x);
}
Run Code Online (Sandbox Code Playgroud)

然后用户键入 …

c c++ integer-overflow undefined-behavior

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

怎么做算术模数另一个数字,没有溢出?

我正在尝试为Rust u32和u64数据类型实现快速素性测试.作为它的一部分,我需要计算(n*n)%d其中n和d是u32(或u64,分别地).

虽然结果很容易适合数据类型,但我对如何计算它感到茫然.据我所知,没有处理器原语.

因为u32我们可以伪造它 - 铸造u64,以便产品不会溢出,然后取模数,然后再回落u32,知道这不会溢出.但是因为我没有u128数据类型(据我所知),这个技巧不起作用u64.

因此,对u64,我能想到的最明显的方式来完成,这是莫名其妙地计算x*y得到一对(carry, product)的u64,所以我们捕获,而不是仅仅失去它(或恐慌,或其他)溢出量.

有没有办法做到这一点?还是另一种解决问题的标准方法?

integer-overflow rust integer-arithmetic modular-arithmetic

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

如何获得R中111111111 * 111111111的正确答案?

我正在向女儿展示R中两个111..111数乘法的魔术模式,例如

> options(scipen=999)
> 1^2
[1] 1
> 11^2
[1] 121
> 111^2
[1] 12321
> 1111^2
[1] 1234321
> 11111^2
[1] 123454321
> 111111^2
[1] 12345654321
> 1111111^2
[1] 1234567654321
> 11111111^2
[1] 123456787654321
> 111111111^2
[1] 12345678987654320
Run Code Online (Sandbox Code Playgroud)

一切正常,直到达到9位数。从最后一行可以看出,答案显然是错误的。它应该是1234567898765432 * 1 *,而不是1234567898765432 * 0 *。

我在Macbook Pro笔记本电脑上的R(v3.6.1,x86_64-apple-darwin15.6.0,64位)中运行此文件。

有人说这可能是整数溢出引起的。这里有两个问题:

  1. 谁能解释这是怎么发生的?例如,最后一个1如何变为0?

  2. 如何在R中获得正确答案?

谢谢。

r integer-overflow

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