我已经包装了一个dll方法,它在Web服务中有一个整数作为out参数.在测试中,我发现当我期待-1时,我得到的是65,535.我意识到dll使用的是16位整数,我在代码中引用外部dll时指定了标准的.NET 32位整数.通过指定一个16位整数很快就可以解决这个问题.
我的问题是为什么会发生这种情况?如果我试图在16位整数中拟合一个32位整数,我可以理解发生溢出但是我不太确定为什么这会发生反过来.显然,我对类型之间的类型铸造的理解有点缺乏,因此任何指导都将受到高度赞赏.
以下是在C++中将unsigned int转换为int的有效且无问题的方法:
#include <limits.h>
void safeConvert(unsigned int passed)
{
int variable = static_cast<int>(passed % (INT_MAX+1));
...
}
Run Code Online (Sandbox Code Playgroud)
或者,还有更好的方法?
UPDATE
正如James McNellis指出的那样,将unsigned int> INT_MAX分配给一个整数并不是未定义的 - 而是实现定义的.因此,此处的上下文现在特别针对我的偏好,即当unsigned int超过INT_MAX时,确保此整数重置为零.
原始背景
我有一些unsigned int用作计数器,但是想要在特定情况下将它们作为整数传递.
在正常操作下,这些计数将保持在INT_MAX的范围内.但是为避免遇到未定义的实现特定行为,如果发生异常(但有效)的情况,我想在这里进行一些有效的转换.
使用Microchip 18f4620 PIC.但这应该是标准的ANSI C问题.
说我有
unsigned int16 badFlow=65535 //max unsigned int16 value
Run Code Online (Sandbox Code Playgroud)
它的二进制值为1111 1111 1111 1111.
如果我那么
badFlow++;
Run Code Online (Sandbox Code Playgroud)
位模式变为1 0000 0000 0000 0000
17位.显然badFlow == 0,但是额外的翻转位也是如此
byte* flowPtr = &badFlow+2;
.我假设后者,但希望前者.
我的问题:一位同事用一个柜台写了一些不好的代码,这个柜台已经在所有生产的产品上溢出了大约2年.考虑到我们的客户对这些工具的使用收费,由于潜在的糟糕数据,这是几百万美元的危险.
在Java中
int x = 0;
(int)(-1.0 / x) -> Integer.MinValue
(int)(1.0 / x) -> Integer.MaxValue
Run Code Online (Sandbox Code Playgroud)
但在C#中,
int x = 0;
(int)(-1.0 / x) -> Int32.MinValue
(int)(1.0 / x) -> Int32.MinValue!!
Run Code Online (Sandbox Code Playgroud)
如果使用"unchecked"语句/运算符,行为将是相同的,如果使用"checked",则它是溢出异常.
但可以肯定的是,在未经检查的上下文中,除了1.0/x(其中x = 0)之外,还会产生Int32.MaxValue,而不是Int32.MinValue.
我错过了什么吗?
这是我的实现,用于检测在尝试添加两个数字时是否发生了无符号的int溢出.
我系统上unsigned int(UINT_MAX)的最大值是4294967295.
int check_addition_overflow(unsigned int a, unsigned int b) {
if (a > 0 && b > (UINT_MAX - a)) {
printf("overflow has occured\n");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这似乎适用于我尝试过的价值观.
任何流氓案件?您认为利弊是什么?
我写下面的代码:
#include <iostream>
using namespace std;
int main() {
unsigned int i=1;
i=i-3;
cout<<i;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是垃圾值,这是可以理解的.
现在我写下面的代码:
#include <iostream>
using namespace std;
int main() {
unsigned int i=1;
i=i-3;
i=i+5;
cout<<i;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在输出是3.这里发生了什么?如何在这里添加垃圾值5?
这是来自Codility的Triangle问题:
给出了一个由N个整数组成的零索引数组A。
如果0≤0,则三元组(P,Q,R)为三角形。P <Q <R <N并且:A [P] + A [Q]> A [R],
A [Q] + A [R]> A [P],
A [R] + A [P]> A [Q]。编写一个函数:
Run Code Online (Sandbox Code Playgroud)int solution(vector<int> &A);如果给定一个由N个整数组成的零索引数组A,则在该数组存在三角形三元组的情况下返回1,否则返回0。
例如,给定数组A使得:
A [0] = 10,A [1] = 2,A [2] = 5,A [3] = 1,A [4] = 8,A [5] = 20三元组(0、2、4)是三角形,该函数应返回1。给定数组A,使得:
A [0] = 10,A [1] = 50,A [2] = 5,A [3] = 1
函数应返回0。假使,假设:
N为[0..100,000]范围内的整数;
数组A的每个元素都是[[2,147,483,648..2,147,483,647]范围内的整数。
这是我在C ++中的解决方案:
int solution(vector<int> &A) {
if(A.size()<3) return 0;
sort(A.begin(), …Run Code Online (Sandbox Code Playgroud) 我想验证是否
pow(a,b)%b == a
在C中为真,2≤b≤32768(2 15)且2≤a≤b,a和b为整数.
但是,直接计算pow(a, b) % bb是一个大数字,这将很快导致C溢出.什么是验证这种情况是否成立的技巧/有效方法?
这个问题是基于找到费马小定理的证人,该定理指出如果这个条件是假的,那么b不是素数.
此外,我在可能的时间也受到限制,它不能太慢(接近或超过2秒).最大卡迈克尔号码,号码b,这不是素数,而且不满足pow(a, b)% b == a与2 <= a <= b(用b <= 32768)是29341.因此,对于检查方法pow(a, b) % b == a具有2 <= a <= 29341不应该太缓慢.
当我在断言测试运行期间遇到一个奇怪的问题时,我正在自学CSAPP并得到一个奇怪的结果.
我不知道该怎么开始这个问题,所以让我先得到代码(文件名在评论中可见):
// File: 2.30.c
// Author: iBug
int tadd_ok(int x, int y) {
if ((x ^ y) >> 31)
return 1; // A positive number and a negative integer always add without problem
if (x < 0)
return (x + y) < y;
if (x > 0)
return (x + y) > y;
// x == 0
return 1;
}
Run Code Online (Sandbox Code Playgroud)
// File: 2.30-test.c
// Author: iBug
#include <assert.h>
int tadd_ok(int x, int y);
int main() {
assert(sizeof(int) == 4); …Run Code Online (Sandbox Code Playgroud) 如何i16在Rust 中将两个数字相加或相乘成一个更大的数i32而不会溢出?
let a: i16 = i16::max_value();
let b: i16 = i16::max_value();
let c: i32 = a + b; // throws EO308 "Expected `u32`, found `u16`
Run Code Online (Sandbox Code Playgroud)