相关疑难解决方法(0)

阈值是绝对值

我有以下功能:

char f1( int a, unsigned b ) { return abs(a) <= b; }
Run Code Online (Sandbox Code Playgroud)

对于执行速度,我想重写如下:

char f2( int a, unsigned b ) { return (unsigned)(a+b) <= 2*b; } // redundant cast
Run Code Online (Sandbox Code Playgroud)

或者使用此签名,即使对于非负面也可能具有微妙含义b:

char f3( int a, int b )      { return (unsigned)(a+b) <= 2*b; }
Run Code Online (Sandbox Code Playgroud)

这两种替代方案都可以在一个平台上进行简单的测试,但我需要便携式.假设非负b且没有溢出风险,这是典型硬件和C编译器的有效优化吗?它对C++也有效吗?


注意:作为C++在gcc 4.8 x86_64上使用-O3,f1()使用6个机器指令并f2()使用4.指令f3()与那些相同f2().同样感兴趣的是:如果b以文字形式给出,则两个函数都编译为3条指令,这些指令直接映射到指定的操作f2().

c c++ micro-optimization undefined-behavior language-lawyer

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

将无符号的负数赋值给有符号,可以吗?

当我运行这个时:

int main() {
    unsigned a = 5;
    std::cout << -a << std::endl;
    int b = -a; 
    std::cout << b << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我明白了:

4294967291
-5
Run Code Online (Sandbox Code Playgroud)

看起来它有效,我可以取 an 的负数unsigned并将其分配给 an int,但这真的总是可以吗?为什么?

当我尝试一些对我来说看起来类似的情况时:

int c = 1;
int d = 3;
double x = c/d;
std::cout << x << std::endl;
Run Code Online (Sandbox Code Playgroud)

我明白了0(正如预期的那样)。

PS:也许有一个骗局,但我没有找到它,我能找到的最接近的是这个

c++ unsigned type-conversion

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

对C++异常处理非常困惑

试图在我的C++程序中添加异常处理,但我觉得它很混乱.程序将值i和j设置为它们的最高可能值并递增它们.我想我希望异常处理在发生时检测整数溢出/环绕(?)

到目前为止,这就是我所拥有的:

#include <iostream>
#include <limits.h>
#include <exception>
#include <stdexcept>
using namespace std;

int main() {
    int i;
    unsigned int j;

    try{
            i = INT_MAX;
            i++;
            cout<<i;
    }
    catch( const std::exception& e){
    cout<<"Exception Error!";
    }   


    try{
            j = UINT_MAX;
            j++;
            cout<<j;
    }
    catch(const std::exception& e){
    cout<<"Exception Error!";
    }
}
Run Code Online (Sandbox Code Playgroud)

程序运行,但异常处理部分不起作用.

可能是什么问题?

c++ exception-handling integer-overflow visual-c++

4
推荐指数
1
解决办法
261
查看次数

C#日期类型转换与c ++相同

如何将ulong转换为long,结果与我在c ++中得到的结果相同.

C++

unsigned long ul = 3633091313;
long l = (long)ul;
l is -661875983
Run Code Online (Sandbox Code Playgroud)

C#

ulong ul = 3633091313;
long l = (long)ul;
l is 3633091313
Run Code Online (Sandbox Code Playgroud)

c# c++ native ulong long-integer

4
推荐指数
1
解决办法
44
查看次数

C++中签名的Integer值溢出?

我有一个遗留的代码库,我们正试图从中迁移devtoolset-4devtoolset-7.我注意到有关有符号整数溢出的有趣行为(int64_t具体而言).

有一个代码片段,用于检测整数溢出,同时乘以一大组整数:

// a and b are int64_t
int64_t product = a * b; 
if (b != 0 && product / b != a) {
    // Overflow
}
Run Code Online (Sandbox Code Playgroud)

这段代码与devtoolset-4一起工作正常.但是,使用devtoolset-7时,永远不会检测到溢出.

例如:当a = 83802282034166b = 98765432, product变为-5819501405344925872(显然值已溢出).

product / b结果价值等于a (83802282034166).因此,if情况永远不会成真.它的值应该根据overflown(负)product值计算:-5819501405344925872 / 98765432 = -58922451788

具有讽刺意味的是,数学是正确的,但它导致devtoolset-4的异常行为.

  • 编译器是否可以缓存该值(而不是重新评估它)导致此行为?
  • 或者编译器优化是否将语句转换product / b != aproduct != a * b并达到相同的溢出值(或者可能只是根据上面的语句跳过计算 …

c++ integer-overflow devtoolset

4
推荐指数
2
解决办法
601
查看次数

int32溢出后有什么可能的值?

我有一个函数,它接受一个字符串作为输入,然后按以下方式将加权值的乘积分配给变量:字母表中的每个字母对应于2到101之间的素数,以及每个字符的值.输入字符串相乘并存储在int变量中,如下所示:

int result=1;
/* some other code */
result*=letterweight[index];
Run Code Online (Sandbox Code Playgroud)

有足够长的字符串会导致溢出.那么,我的问题如下:

在给定结果的情况下,如何确定可能的正确值?

例如:if result == 1066849907,是否会产生其他值,忽略intC中的值范围?

我无法控制原始代码,无法确定是否发生溢出.我只想找出一系列可能的结果,无论这个数字有多大.

c c++ algorithm

2
推荐指数
1
解决办法
144
查看次数

类型铸造差异

在以下代码中:

#include<cstdio>
#define max(a,b) (a>b?a:b)
using namespace std;

int main()
{
    int f=10000000;

    long long i=(long long)max(1000000,f*f);
    printf("%lld",i);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到了输出

276447232

但如果我写

long long i=max((long long)1000000,(long long)f*f);
Run Code Online (Sandbox Code Playgroud)

我得到了输出

百兆

这两条线有什么区别?为什么在第一种情况下不会发生类型转换?

c++ algorithm syntax

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

cprinting使用整数赋值给字符的Ascii

我试图打印Ascii字符,我发现使用char c = NUM; printf("%c", c);将适用于某些数字(尝试使用Ascii数字的某些字母表)但有些会导致运行时错误,为什么会这样?

#include <stdio.h>

int main(void) {
    for(int i = 0; i < 128; i++){
        printf("%c", i); // WORKS FINE
    }

    for(char c = '!'; c < '~'; c++){
        printf("%c", c); //WORKS FINE
    }

    #if 0
    for(char d = 0; d < 128; d++){
        printf("%c", d); //IF REMOVED #if 0 --> RUNTIME ERROR
    }
    #endif

    // HOWEVER
    char e = 105;
    printf("%c", e); //OK
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

那么,为什么最后一部分工作而第三部分for循环不是?

编辑

在看到下面的答案之后,我明白我的循环已经病态了,我应该在127而不是128停止它.但是,当我尝试这个改变时 - 它根本没有输出:

for(unsigned char …
Run Code Online (Sandbox Code Playgroud)

c ascii char

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

为什么这两行产生不同的溢出行为?

如果intA*intB结果足够大,则会在2 ^ 31边界溢出,并且您无法获得预期的结果.

int64_t value = (intA * intB) - int64A

然而,这产生了预期值.

int value = (intA * intB) - int64A

在低级别发生了什么意味着存储在int中的相同(坏)操作是正确的,但是在int64_t中却没有?

c++

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

int16_t如何表示大于32767且不翻转的数字

在 Arduino Uno 上运行的这段代码会打印递增的数字,并按预期从 32767 回绕到 -32768。

int16_t i = 0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  i++;
  Serial.println(i);
}
Run Code Online (Sandbox Code Playgroud)

然而,人们认为在功能上等效的这段代码不断打印超过 200000 个 16 位数字(有符号或无符号)应该能够表示的数字。

void setup() {
  Serial.begin(115200);

  int16_t i = 0;

  while(true) {
    i++;
    Serial.println(i);
  }
}

void loop() {}
Run Code Online (Sandbox Code Playgroud)

Arduino 参考中有关于数据类型的注释/警告int。这有关系吗?

当有符号变量超过其最大或最小容量时,它们就会溢出。溢出的结果是不可预测的,因此应该避免这种情况。溢出的典型症状是变量从最大容量“滚动”到最小容量,反之亦然,但情况并非总是如此。如果您想要这种行为,请使用 unsigned int。

第二个代码片段发生了什么?变量如何明显代表这么大的数字而不滚动?

c++ types arduino

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