在C,C++(stdlib.h)中有一个名为div的函数
div_t div(int numer, int denom);
typedef struct _div_t
{
int quot;
int rem;
} div_t;
Run Code Online (Sandbox Code Playgroud)
但是C,C++有/和%运算符.
我的问题是:" 当有/和%运算符时,div函数有用吗?"
我是Python新手,我现在正在学习操作员.我明白:
/运营商用于floating point division和//对integer division.例:
7//3 = 2
Run Code Online (Sandbox Code Playgroud)
并且7//-3=-3.为什么答案-3?
我被困在这里.
我知道如何为2的权力做到这一点,所以这不是我的问题.
例如,如果我想使用位移而不是整数除法找到5%的数字,我将如何计算?
因此,我可以做(x*100 >> 11)而不是(x*20/19).现在这不对,但它很接近,我通过反复试验来到它.我如何确定最可能使用的精确班次?
如果这是一个简单的问题,我很抱歉,但是当第一个数字小于第二个数字时,我无法理解模数除法的概念.例如,当我的书中1%4表示余数为1.我不明白1是1%4的剩余部分
.1/4是0.25.我在考虑模数除法错误吗?
我在C++中使用整数除法面临一些奇怪的结果.我想计算一下:-2147483648/-1.
我得到的是3种不同场景中的3种不同结果:
int foo(int numerator, int denominator) {
int res = numerator / denominator; // produces SIGFPE, Arithmetic exception interrupt
cout << res << endl;
}
int main() {
int res = -2147483648 / -1;
cout << res << endl; // prints -2147483648
cout << -2147483648 / -1 << endl; // prints 2147483648
foo(-2147483648, -1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么整数除法运算在不同情况下会产生不同的结果?
我正在编写类似于mpz(C)或BigInteger(Java)的类.这只是为了好玩,所以请不要继续谈论我不应该如何写自己的.
我有一个类似于的类:
public class HugeInt
{
public List<Integer> digits;
public HugeInt(String value)
{
// convert string value into its seperate digits.
// store them in instance variable above
}
}
Run Code Online (Sandbox Code Playgroud)
现在,执行此类的add()和subtract()方法非常简单.这是一个例子:
private List<Integer> add(List<Integer> a, List<Integer> b)
{
List<Integer> smallerDigits = (compareDigits(a,b) < 0) ? a : b;
List<Integer> largerDigits = (compareDigits(a,b) >= 0) ? a : b;
List<Integer> result = new ArrayList<Integer>();
int carry = 0;
for(int i = 0; i < largerDigits.size(); i++)
{
int num1 = largerDigits.get(i); …Run Code Online (Sandbox Code Playgroud) 来源我的回答:
我有点不在这里,我试图了解这种特殊优化是如何工作的.
正如答案中提到的,gcc将整数除法优化为7:
mov edx, -1840700269
mov eax, edi
imul edx
lea eax, [rdx+rdi]
sar eax, 2
sar edi, 31
sub eax, edi
Run Code Online (Sandbox Code Playgroud)
其转换为C为:
int32_t divideBySeven(int32_t num) {
int32_t temp = ((int64_t)num * -015555555555) >> 32;
temp = (temp + num) >> 2;
return (temp - (num >> 31));
}
Run Code Online (Sandbox Code Playgroud)
我们来看看第一部分:
int32_t temp = ((int64_t)num * -015555555555) >> 32;
Run Code Online (Sandbox Code Playgroud)
为什么这个号码?
那么,让我们取2 ^ 64并将其除以7,看看弹出的是什么.
2^64 / 7 = 2635249153387078802.28571428571428571429
Run Code Online (Sandbox Code Playgroud)
这看起来像一团糟,如果我们把它转换成八进制怎么办?
0222222222222222222222.22222222222222222222222
Run Code Online (Sandbox Code Playgroud)
这是一个非常漂亮的重复模式,当然这不是巧合.我的意思是我们记得7是0b111,我们知道当我们除以99时,我们倾向于在基数10中得到重复模式.因此,当我们除以7时,我们在基数8中得到重复模式是有道理的.
那么我们的号码在哪里?
(int32_t)-1840700269 是相同的 (uint_32t)2454267027
* 7 …
algorithm math optimization integer-division compiler-optimization
看看这段代码
int main()
{
int i = 1U << 31; // assume this yields INT_MIN
volatile int x;
x = -1;
x = i / x; //dividing INT_MIN by -1 is UB
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它在典型平台上调用未定义的行为,但"行为"与我的预期完全不同 - 它就好像它是一个无限循环.我能想到它咬人的场景.
当然未定义是未定义的,但我检查了输出程序集,它使用了一个简单的idiv- 为什么它不陷阱?为了便于比较,除以零会导致立即中止.
使用Windows 7 64位和MingW64
任何人都可以向我解释这个吗?
编辑
我尝试了几个选项,结果总是一样的.
这是集会:
.file "a.c"
.def __main; .scl 2; .type 32; .endef
.section .text.startup,"x"
.p2align 4,,15
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
subq $56, %rsp
.seh_stackalloc 56
.seh_endprologue …Run Code Online (Sandbox Code Playgroud) 我正在研究一个6502 cpu的汇编语言程序,我发现我需要一个快速尽可能快的七分程序,特别是一个可以获得16位分红的程序.
我熟悉这里发现的例程,但是对七分法例程进行了概括,发现它非常复杂,粗略地检查了一般算法(使用整数除法)
x/7~ =(x + x/8 + x/64 ...)/ 8
表示要处理16位范围,由于6502的单个累加器寄存器和6502上各个存储器位移的相对慢速,可能需要100多个周期才能完成.
我认为查找表可能会有所帮助,但在6502上,我当然只限于256字节或更少的查找表.为此,可以假设存在两个256字节的查找表xdiv7和xmod7,当使用无符号的单字节值作为表的索引时,可以快速获得字节除以7或模数的结果分别为7.但是,我不确定如何利用它们来查找完整16位范围的值.
与此同时,我还需要一个模7算法,尽管理想情况下,可以通过除法得到的解决方案也会产生mod7结果.如果需要额外的预计算表,只要所有表的总内存需求不超过约3k,我就可以添加这些表.
虽然我最终需要一个带符号的除法算法,但是一个无符号算法就足够了,因为我可以根据需要将它推广到一个有符号的例程.
任何帮助将不胜感激.
我的程序经常需要执行以下计算:
鉴于:
找:
显然我可以直接使用r=x*n/d,但经常会从中溢出x*n。如果我改为这样做,r=x*(n/d)则由于整数除法会除去小数部分,因此我只会得到0或x。然后有,r=x*(float(n)/d)但在这种情况下我不能使用浮点数。
精度会很高,但并不像速度和决定性功能那么关键(总是在给定相同输入的情况下返回相同的值)。
N和D当前已签名,但如果有帮助,我可以解决它们始终未签名的问题。
可以使用任何X值(以及N和D,只要N <= D)的泛型函数是理想的,因为此操作以各种不同的方式使用,但是我也有一个特殊的情况,其中X的值是已知的保持2的幂(准确地说是2048),并且加快特定的调用速度将是一个很大的帮助。
目前,我正在使用64位乘法和除法来完成此操作,以避免溢出(本质上是,int multByProperFraction(int x, int n, int d) { return (__int64)x * n / d; }但是有一些断言和多余的位数摆弄而不是舍入)。
不幸的是,我的探查器报告64位除法函数占用了过多的CPU(这是一个32位应用程序)。我尝试减少执行此计算的频率,但用尽了很多方法,因此,即使有可能,我也在尝试找出一种更快的方法。在X的常数为2048的特定情况下,我使用了移位而不是乘法,但这并没有太大帮助。