0 .. v.len() - 1当向量v可能为空时,正确的循环方法是什么?
考虑以下代码,它打印向量中 2 个元素的所有选择[5, 6, 7]:
fn main() {
let v: Vec<i32> = vec![5, 6, 7];
for i in 0 .. v.len() - 1 {
for j in i + 1 .. v.len() {
println!("{} {}", v[i], v[j]);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它打印
5 6
5 7
6 7
Run Code Online (Sandbox Code Playgroud)
正如预期的那样。
现在,如果我们有
let v: Vec<i32> = vec![];
Run Code Online (Sandbox Code Playgroud)
那么程序就会因为溢出而出现恐慌,这也是意料之中的。
问:如何在不改变程序结构和逻辑、不涉及有符号整数的情况下修复它?
以下是我不想要的解决方法的一些示例:
单独处理空v(改变逻辑)。总的来说,我不想要任何v空支票,例如if v.len() == 0 { 0 } …
这是我的OpenGL代码的一部分,我得到一个错误:
struct Ball {
float x;
float y;
float rot;
float dir;
bool rmv;
Ball* next;
};
Ball* curBall;
void addBall() {
if (balls==NULL) {
balls=new Ball;
balls->next=NULL;
curBall=balls;
} else {
curBall->next=new Ball;
curBall=curBall->next;
curBall->next=NULL;
}
curBall->x=((float)rand()/(float)(RAND_MAX+1))*(ww-1) +1;
curBall->y=((float)rand()/(float)(RAND_MAX+1))*(wh-1) +1;
curBall->dir=((float)rand()/(float)(RAND_MAX+1))*(2*PI-1) +1;
curBall->rot=((float)rand()/(float)(RAND_MAX+1))*(359) +1;
curBall->rmv=false;
}
Run Code Online (Sandbox Code Playgroud)
error :
In function ‘void addBall()’:
file.cpp:120: warning: integer overflow in expression
file.cpp:121: warning: integer overflow in expression
file.cpp:122: warning: integer overflow in expression
file.cpp:123: warning: integer overflow in expression
Run Code Online (Sandbox Code Playgroud) 这是代码:
#include <stdio.h>
int main()
{
int i = 3;
int *p = &i;
p - (p - 1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器(gcc)警告外部减法的整数溢出:
[user@comp c]$ gcc foo.c
foo.c: In function ‘main’:
foo.c:6:5: warning: integer overflow in expression [-Woverflow]
p - (p - 1);
^
Run Code Online (Sandbox Code Playgroud)
在我的机器上获得了正确的结果1.
为什么?
这是因为指针地址是无符号整数但是ptrdiff_t是一个有符号的int并且无法处理那些大数字?
我看到了
p - (p);
Run Code Online (Sandbox Code Playgroud)
和
p - (p + 1);
Run Code Online (Sandbox Code Playgroud)
不要引起溢出.
我试图了解幕后发生的事情.这是我关于stackoverflow的第一个问题,如果我的问题可以改进,请告诉我.
例如,给出以下代码:
int f(int n)
{
if (n < 0)
return 0;
n = n + 100;
if (n < 0)
return 0;
return n;
}
Run Code Online (Sandbox Code Playgroud)
假设您传入的数字非常接近整数溢出(小于100),编译器是否会生成会给您带来负回报的代码?
以下是Simon Tatham的"The Descent to C"中关于这个问题的摘录:
"GNU C编译器(gcc)为这个函数生成代码,它可以返回一个负整数,如果你传入(例如)最大表示能够'int'的值.因为编译器在第一个if语句后知道n是正数,然后它假设不发生整数溢出,并使用该假设得出结论,在加法后n的值必须仍为正,因此它完全删除第二个if语句并返回未选中的加法结果.
它让我想知道C++编译器中是否存在同样的问题,如果我不小心我的整数溢出检查不会被跳过.
c++ compiler-construction gcc integer-overflow undefined-behavior
我的MASM上有点生疏,所以我真的不记得在这里做什么(如果有什么需要做的话).我有一个MASM(X86)例程,如下所示.它有两个局部变量,共占用5个字节:
MSC_ASM_GenerateBlock PROC buffer:DWORD,bsize:DWORD,safety:DWORD
LOCAL val:DWORD, rc:BYTE ;; local variables
MWSIZE EQU 4 ;; machine word size
.WHILE bsize >= MWSIZE && safety > 0
;; RDRAND is not available prior to VS2012. Just emit
;; the byte codes using DB. This is `rdrand eax`.
DB 0Fh, 0C7h, 0F0h
setc rc
...
.ENDW
...
MSC_ASM_GenerateBlock ENDP
Run Code Online (Sandbox Code Playgroud)
当我检查拆卸时,我看到:
> dumpbin.exe /DISASM rdrand-x86.obj
Dump of file rdrand-x86.obj
_MSC_ASM_GenerateBlock:
00000000: 55 push ebp
00000001: 8B EC mov ebp,esp
00000003: 83 C4 F8 add …Run Code Online (Sandbox Code Playgroud) 我试图将一个"大"因子转换为R中的一组指标(即虚拟,二元,标志)变量:
FLN <- data.frame(nnet::class.ind(FinelineNumber))
Run Code Online (Sandbox Code Playgroud)
这里FinelineNumber是从Kaggle.com目前沃尔玛大赛5000级因子(该数据是公开的,如果你想重现此错误).
我一直得到这个看起来很有意思的警告:
In n * (unclass(cl) - 1L) : NAs produced by integer overflow
系统可用的内存基本上是无限的.我不确定问题是什么.
我有一些代码,我很久以前做过(当时我正在使用visual studio 2003).现在我正在使用gcc并且一些值已经溢出,我看看发生了什么,这让我感到惊讶.
让我来说明发生了什么:
作品(输出= 85):
int b = 35000000;
unsigned long a = 30000000;
unsigned long n = ( 100 * a ) / b;
Run Code Online (Sandbox Code Playgroud)
不起作用(溢出):
int b = 35000000;
int a = 30000000;
unsigned long n = ( 100 * a ) / b;
Run Code Online (Sandbox Code Playgroud)
不起作用(溢出):
int b = 35000000;
unsigned long n = ( 100 * 30000000 ) / b;
Run Code Online (Sandbox Code Playgroud)
这一切都应该是正确的.现在有什么不好的是:
unsigned long b= 35000000;
unsigned long n = ( 100 * 30000000 ) / b;
Run Code Online (Sandbox Code Playgroud)
曾经工作!现在它没有.
好吧,实际上它仍适用于微软编译器,但它不适用于clang和gcc.如果您愿意,可以使用不同的编译器进行编译: …
c++ standards integer-overflow compiler-warnings language-lawyer
这个问题可能只是另一种不正确地解释操作员的情况.但不久之前,我看到有人发推文关于一个运营商的信息,据称可以用来检查C中的整数溢出.即&+(&符号加)运算符,它可以像这样使用:
#include <stdio.h>
#include <stdint.h>
int main()
{
uint32_t x, y;
x = 0xFFFFFFFF;
y = 1;
if (x &+ y) {
printf("Integer overflow!\n");
} else {
printf("No overflow\n");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它看起来确实像人们期望的那样工作,GCC 6在使用这些参数进行编译时不会给我任何警告或错误: gcc -Wall -Wextra -Werror of.c
但奇怪的是,我还没有找到关于这个运算符的任何文档,我从来没有看到它在任何地方使用过.有人可以解释一下这是如何工作的?
以下证据表明:
inline
constexpr std::size_t prev(std::size_t i) {
--i;
return i;
}
int main() {
static const std::size_t i = 0;
static_assert(prev(i) == std::size_t(-1), "Decrementing should give std::size_t(-1)");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
那个快乐地汇编着-std=c++14.
我遇到了这个,因为我有一个循环索引,std::vector并想要向后循环,所以我把它改为
for (std::size_t i = std::min(idx, v.size() - 1); i != std::size_t(-1); --i) { ... }
Run Code Online (Sandbox Code Playgroud)
现在,我意识到我可以使用std::vector::reverse_iterator,但我现在的真正问题是,我期待定义的行为是什么?
我有两个大的np.uint8 ndarrays,a和b。我需要计算:c = np.sum(np.abs(a - b), axis=(-2,-1,))
由于它们是未签名的,所以我不能仅减去它们。一种简单的解决方法是将它们转换为更大的数据类型:
c = np.sum(np.abs(a.astype(np.int16) - b.astype(np.int16)), axis=(-2,-1,))
Run Code Online (Sandbox Code Playgroud)
其中在总使用4 *倍数组的内存。在理想的世界中,我想成为这样的人:
c = np.sum(np.abssub(a, b), axis=(-2,-1,))
Run Code Online (Sandbox Code Playgroud)
它将使用与阵列相同的内存量。可悲的是,我在numpy的文档中找不到这样的功能。目前,我正在执行以下操作:
diff = np.empty_like(a)
mask = a > b
diff[mask] = (a - b)[mask]
# b shape is different but broadcasts to a
# That is why I use mask after substracting
mask = np.logical_not(mask, out=mask)
diff[mask] = (b - a)[mask]
c = np.sum(np.abs(diff, out=diff), axis=(-2,-1,))
Run Code Online (Sandbox Code Playgroud)
其用途是仅仅 2.5 **的存储器中作为阵列倍量。
有一个更好的方法吗?
* …Run Code Online (Sandbox Code Playgroud)