任何人都可以提供一些代码示例,当使用fwrapv vs编译时,它们的行为会有所不同.
它说--fwrapv应该"假设加法,减法和乘法的带符号算术溢出,使用二进制补码表示包装."
但每当我尝试溢出时,结果与fwrapv相同或不同.
可能重复:
大数的乘法,如何捕获溢出
接近C,C++和D等金属语言,什么是最有效的合理可移植方式(即使用汇编程序,虽然你可以假设两个补码算法和环绕行为)来检测无符号64位的溢出乘法时的整数?
在C/C++中是否有一种合理的可移植方式可以将128位结果乘以两个64位整数并获得结果的前 64位而不是底部的64位?我需要这个来在任意大小的表上分配哈希函数.
如果以下任何一项符合标准的方式做"正确的事"?你可以假设m,并n有型int(有符号整数).主要问题是有符号整数溢出.
样品1.
size_t bytes = n * m;
if (n > 0 && m > 0 && SIZE_MAX/n >= m) {
/* allocate “bytes” space */
}
Run Code Online (Sandbox Code Playgroud)
样本2.
if (n > 0 && m > 0 && SIZE_MAX/n >= m) {
size_t bytes = n * m;
/* allocate “bytes” space */
}
Run Code Online (Sandbox Code Playgroud)
样本3.
if (n > 0 && m > 0 && SIZE_MAX/n >= m) {
size_t bytes = (size_t)n * (size_t)m;
/* …Run Code Online (Sandbox Code Playgroud) 在Hacker的喜悦中,有一种算法来计算两个(带符号)单词的双字产品.
该函数muldws1使用四次乘法和五次加法来计算两个单词的双字.
在该代码的末尾有一行注释掉
/* w[1] = u*v; // Alternative. */
Run Code Online (Sandbox Code Playgroud)
该替代方案使用五次乘法和四次加法,即它为乘法交换加法.
但我认为这种替代方法可以改进.我还没有说过硬件.让我们假设一个假设的CPU,它可以计算两个字但不是高位字的乘积的低位字(例如,对于32位字32x32到低32).在这种情况下,在我看来,这个算法可以改进.这是我假设32位字的想法(相同的概念适用于64位字).
void muldws1_improved(int w[], int32_t x, int32_t y) {
uint16_t xl = x; int16_t xh = x >> 16;
uint16_t yl = y; int16_t yh = y >> 16;
uint32 lo = x*y;
int32_t t = xl*yh + xh*yl;
uint16_t tl = t; int16_t th = t >>16;
uint16_t loh = lo >> 16;
int32_t cy = loh<tl; //carry
int32_t hi = xh*yh + th …Run Code Online (Sandbox Code Playgroud) 如果两个数字的乘法大于ULONG_MAX限制,我需要编写一个返回true的函数。否则返回false。
我尝试了以下方法:
bool isGtThanULONG_MAX(double A, double B) {
double result = A * B;
if (result > ULONG_MAX)
return true;
else
{
//If this could be due to overflow, then again check:
double temp = result / A;
if (A != 0 && (temp != B)) {
// overflow handling
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
}
输出:下面 cout 语句中的第 1 行和第 4 行给出了 OVERFLOW(这显然是错误的输出),其余的在输出中给出了 NO-OVERFLOW(这是正确的)。为什么会失败?我错过了什么吗?请帮忙。
cout << (isGtThanULONG_MAX(10, 0.0000000000000000001) == true ? …Run Code Online (Sandbox Code Playgroud) 当我尝试优化我的代码时,很长一段时间我一直在使用经验法则,加法和减法值1,乘法和除法值3,平方值3(我很少使用更通用的pow函数所以我对它没有经验法则,并且平方根值10.(我假设平方数只是乘法,所以值得3.)
这是2D轨道模拟的一个例子.要计算并应用重力加速度,首先我得到从船到地球中心的距离,然后计算加速度.
D = sqrt( sqr(Ship.x - Earth.x) + sqr(Ship.y - Earth.y) ); // this is worth 19
A = G*Earth.mass/sqr(D); // this is worth 9, total is 28
Run Code Online (Sandbox Code Playgroud)
但是,请注意,在计算D时,您采用平方根,但在下一次计算中使用它时,您将其平方.因此你可以这样做:
A = G*Earth.mass/( sqr(Ship.x - Earth.x) + sqr(Ship.y - Earth.y) ); // this is worth 15
Run Code Online (Sandbox Code Playgroud)
因此,如果我的经验法则属实,我几乎减少了一半的周期时间.
但是,我甚至不记得以前在哪里听过这条规则.我想问一下这些基本算术运算的实际循环时间是多少?
假设:
编辑:我想我真正要做的是查看ALU内部并仅计算6个操作的逻辑循环时间.如果其中仍存在差异,请说明原因和原因.
注意:我没有看到任何机器代码的标签,所以我选择了下一个最接近的东西,汇编.为了清楚起见,我在谈论x64架构中的实际机器代码操作.因此,我写的那些代码行是用C#,C,Javascript还是无关紧要.我敢肯定每种高级语言都会有不同的时间,所以我不想讨论这个问题.我认为没有机器代码标签是一种遗憾,因为在谈论性能和/或操作时,你真的需要深入了解它.
我想在不使用64位数据类型的情况下进行32位有符号整数乘法.我的输入是Q1.31(两种)格式.
input1 = A32 (Ah Al) - higher, lower half's of A32
input2 = B32 (Bh Bl) - higher, lower half's of B32
Run Code Online (Sandbox Code Playgroud)
结果应为Q1.31格式,保留溢出情况.
我需要C代码.请提供格式说明.