我希望alwaysPositive被分配一个正数,其中包含lareValue1和largeValue2的所有可能值(这些值至少为1).
以下语句导致缓冲区溢出:
int alwaysPositive = (largeValue1 + largeValue2) / 2;
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过减去和添加来阻止它:
int alwaysPositive = largeValue1 + ((largeValue2 - largeValue1) / 2);
Run Code Online (Sandbox Code Playgroud)
但在其他编程语言中,我可以使用无符号位移来实现这一诀窍:
int alwaysPositive3 = (largeValue1 + largeValue2) >>> 1;
Run Code Online (Sandbox Code Playgroud)
我怎么能在C#中做到这一点?
以下答案都解决了这个问题.可能有很多方法可以做到这一点,但它们(包括我的解决方案)都有一个共同点:它们看起来都是混淆的.
换句话说,这是否按预期工作?
int32 i = INT_MAX-1;
int64 j = i * i;
Run Code Online (Sandbox Code Playgroud)
或者我需要先将i转换为64位?
我能用valgrind检测整数溢出缺陷吗?它中的哪个工具可以做到这一点?
我已经学会了(至少在java中)整数/长值静默地溢出,它们的值从溢出时的最小值开始而不是抛出任何异常.
我正在使用外部api进行某些文件操作,其中从文件属性加载最大文件大小.在我当地的测试环境中一切都很好.代码进入实时环境后,最大文件大小限制根本不起作用.经过两天调试/分析代码后,根本没有成功.然后由于其他原因,我采用了live constants.properties文件并用它调试了代码.O_0
我只想问,是什么阻止他们在溢出时抛出异常?
所以我刚刚学会了声明Object类型的变量(即Object a;)时,为该变量分配了32位空间.在这个变量/引用中,有一个实际Object的内存地址.
现在让我们假装我有足够的内存来做这件事.
如果我创建了超过4,294,967,296(2 32)个Object类型的变量并尝试将它们分配给不同的对象会发生什么?由于整数溢出,某些变量/引用是否会获得相同的内存地址?这意味着在内存中引用超过4,294,967,296个对象是不可能的?
如标题中所示.作为练习,我想创建一个int来强制对其值进行约束,并且不允许将其设置为超出其指定范围的值.
以下是我尝试解决此问题的方法:
#include <cassert>
#include <cstdint>
#include <iostream>
using namespace std;
int main();
template<typename valtype, valtype minval, valtype maxval>
class ConstrainedValue
{
valtype val;
static bool checkval (valtype val)
{
return minval <= val && val <= maxval;
}
public:
ConstrainedValue() : val{minval} // so that we're able to write ConstrainedValue i;
{
assert(checkval(val));
}
ConstrainedValue(valtype val) : val{val}
{
assert(checkval(val));
}
ConstrainedValue &operator = (valtype val)
{
assert(checkval(val));
this->val = val;
return *this;
}
operator const valtype&() // Not …Run Code Online (Sandbox Code Playgroud) 我正在将一些旧的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
这个特殊的术语似乎很难谷歌.
更新:答案是溢出运算符,它们是
&- 减法&+ 另外&* 为了倍增我在之前的搜索中找不到它们.哎呀
让我们考虑一个函数(它的可能实现之一),它将无符号短值(或任何其他无符号整数类型)的右N位置零.可能的实现可能如下所示:
template<unsigned int shift>
unsigned short zero_right(unsigned short arg) {
using type = unsigned short;
constexpr type mask = ~(type(0));
constexpr type right_zeros = mask << shift; // <-- error here
return arg & right_zeros;
}
int check() {
return zero_right<4>(16);
}
Run Code Online (Sandbox Code Playgroud)
使用此代码,我可以访问的所有编译器以某种方式抱怨可能的溢出.CLang是最明确的一个,有以下明确的信息:
错误:从'int'到'const type'的隐式转换(又名'const unsigned short')将值从1048560更改为65520 [-Werror,-Wconstant-conversion]
这个代码看起来很清晰,对我来说很明显,但是当3个编译器抱怨时,我变得非常紧张.我在这里错过了什么吗?真的有可能发生腥病吗?
PS虽然zeriong out左边X位的替代实现可能是受欢迎和有趣的,但这个问题的主要焦点是发布的代码的有效性.
我目前正在阅读一本关于C#编程的书,它简要介绍了溢出和下溢,并且作者总结了当你超越特定类型的允许范围时会发生什么.
例
short a = 30000;
short b = 30000;
short sum = (short)(a + b); // Explicitly cast back into short
Console.WriteLine(sum); // This would output the value -5536
Run Code Online (Sandbox Code Playgroud)
所以short类型只有-32768到32767的范围,书中给出的解释是"对于整数类型(byte,short,int和long),最高位(溢出)被丢弃这是特别奇怪的,因为计算机然后将其解释为环绕.这就是我们在示例中最终得到负值的原因.如果从特定类型的最大值开始,您可以很容易地看到这种情况发生(例如,short.MaxValue)并添加一个." C#Players Guide第二版,第9章,第58页
你最终会达到最低限度(-32768).
我有一个问题理解这一点当作家谈到"计算机将其解释为环绕"时我感到困惑
我尝试理解这个的方式是短类型使用2个字节(16位)
所以数字32767 = 0111111111111111,如果我要+1到二进制字符串我最终得到32768 = 1000000000000000(不能用短类型表示为最大值是32767)所以编译器给出-32768.为什么它最终成为负面?
我理解使用二元恭维来表示负数的概念,有人可以在这里纠正我的想法或详细说明因为我不完全理解为什么我们只使用16位的15位来表示正范围和最重要的位负范围
在另一个线程中,有人问为什么将两个ushort值相加会引起C#错误。例如
ushort x = 4;
ushort y = 23;
ushort z = x+y; // ERROR cannot implicitly convert int to ushort
Run Code Online (Sandbox Code Playgroud)
在该线程上,人们认为加号+运算符默认情况下采用两个整数,并且这是一种有助于避免算术溢出的语言功能。但是我在以下函数中遇到了相同类型的错误:
public RGB(ushort red, ushort green, ushort blue)
{
// this class RGB has three ushort fields: r, g, and b
r = red % ((ushort)256);
g = green % ((ushort)256);
b = blue % ((ushort)256);
}
Run Code Online (Sandbox Code Playgroud)
编译器出错并说“无法将类型'int'隐式转换为'ushort'。存在显式转换...”。但是,这里所说的模%运算符可以防止溢出的说法根本没有任何意义:如果x和y是ushort值,则x%y < max(x,y),因此不存在溢出为整数的风险。那我为什么会收到这个错误?