分而治之-C/C++库函数和运算符是最理想的函数和运算符吗
divide and conquer - Are C/C++ library functions and operators the most optimal ones?
因此,在除法&我们被教导的征服课程:
- Karatsuba乘法
- 快速求幂
现在,给定2个正整数a和b,operator::*
比karatsuba(a,b)
快,或者pow(a,b)
比快
int fast_expo(int Base, int exp)
{
if (exp == 0) {
return 1;
}
if (exp == 1) {
return Base
}
if (exp % 2 == 0) {
return fast_expo(Base, exp / 2) * fast_expo(Base, exp / 2);
}
else {
return base * fast_expo(Base, exp / 2) * fast_expo(Base, exp / 2);
}
}
我问这个问题是因为我想知道它们是否只是一个教学目的,或者它们已经在C/C++语言中基本实现了
Karatsuba乘法是一种用于大整数的特殊技术。它不能与内置的C++*
运算符相比,后者将基本类型的操作数(如int
和double
(相乘在一起。
要利用Karatsuba,您必须使用至少由8个单词组成的多精度整数。(如果这些是64位字,则为512位(。根据这个问题的公认答案,Karatsuba变得有利的盈亏平衡点在8到24个机器词之间。
与一对类型为double
的浮点操作数一起使用的pow
函数与您的fast_expo
(与类型为int
的操作数一起工作(不可同日而语。它们是不同的功能,有不同的要求。使用pow
,可以计算5:pow(5, 1/3.0)
的立方根。如果这是你想要计算的,那么fast_expo
无论有多快都没有用。
不能保证编译器或C库的pow
绝对是机器对两个双精度浮点数求幂的最快方法。
浮点中的优化声明可能很棘手,因为通常情况下,"同一"函数的多个实现直到最后一位都不会给出完全相同的结果。您可能可以编写一个精度仅为小数点后五位的快速my_pow
,在您的应用程序中,这种近似可能绰绰有余。你打败图书馆了吗?几乎不您的fast函数不符合将其作为库中pow
的替代品的要求。
operator::*
和其他标准运算符通常映射到硬件提供的基元。如果不存在这样的基元(例如,IA32上的64位long long
(,编译器会以性能为代价来模拟它们(gcc在libgcc
中这样做(。
与std::pow
相同。它是标准库的一部分,并没有强制要求以某种方式实现。GNU libc将pow(a,b)
实现为exp(log(a) * b)
。CCD_ 23和CCD_。
至于你的建议:
小数字的Karatsuba乘法不值得。处理器提供的乘法机指令已经针对使用中的标准数据类型的速度和功耗进行了优化。有了更大的数字,10-20倍的寄存器容量,它开始有回报:
在GNU MP Bignum库中,曾经有一个默认的非模块乘法的
KARATSUBA_THRESHOLD
高达32(也就是说,当n>=32w
与典型的w=32
时使用Karatsuba(;模幂运算的最优阈值趋向于显著更高。在现代CPU上,软件中的Karatsuba倾向于对于P-256上的ECDSA(n=256
、w=32
或w=64
(,但是可以想象对于RSA中使用的宽得多的模量是有用的。
下面列出了GNUMP使用的乘法算法及其各自的阈值。
快速求幂不适用于非整数幂,因此它实际上无法与pow
相比。
检查操作速度的一个好方法是测量它。如果你运行大约十亿次计算,看看执行需要多少时间,你就有答案了。
有一点需要注意。我相信%是相当昂贵的。有一种更快的方法可以检查某个东西是否可以被2:整除
check_div_two(int number)
{
return ((number>>1) & 0x01);
}
通过这种方式,你只是做了一点改变,并与口罩进行了比较。我认为这是一个比较便宜的操作。
内置类型的*
运算符几乎肯定会作为单个CPU乘法指令来实现。所以归根结底,这是一个硬件问题,而不是语言问题。在没有直接硬件支持的情况下,可能会生成更长的代码序列,可能是函数调用。
可以肯定的是,芯片制造商(英特尔、AMD等(花费了大量精力使算术运算尽可能高效。
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 最小硬币更换问题(自上而下方法)
- 使用指针从C++中的数组中获取最大值
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- 余数运算符的等效操作,用于处理低于允许的最小值
- 从小于或等于某个 N 的数字列表中最小化或找到 n 个理想的子集和
- 最小值/最大值二元运算符
- 为什么按位运算符在使用与整数中提供的位数相同的位数计算可能的最大范围时会产生错误
- 在没有比较运算符的情况下查找 2 个数字之间的最小值
- 哪种检查方法比设置值最理想
- 如何在三重运算符的帮助下通过最大值完成地图
- 将多个值与同一变量进行比较时'!='运算符最简洁的方法是什么?
- 最理想的情况是,如果一个变量在多个线程中读取,但只在一个线程中写入,那么它是否应该在写入线程中以非原子方式读取
- 比较位集的最快方法(<位集上的运算符)?
- 如何在最大限度地提高大小有效性的同时,将3态的位运算符实现为任何大小的内存
- 了解具有最小stl优先级_queue的运算符()重载
- C/C++宏,用于在不使用三元运算符的情况下查找两个数字的最大值
- 分而治之-C/C++库函数和运算符是最理想的函数和运算符吗