在C中编写饱和加法的最佳(最干净,最有效)方法是什么?
函数或宏应添加两个无符号输入(需要16位和32位版本),如果总和溢出,则返回所有位 - 一(0xFFFF或0xFFFFFFFF).
目标是x86和ARM使用gcc(4.1.2)和Visual Studio(仅用于模拟,因此可以使用后备实现).
c algorithm performance signal-processing saturation-arithmetic
我记得有一种方法可以使用扩展的gcc内联汇编来读取寄存器值并将其存储到C变量中.我不能为我的生活记住如何形成asm陈述.任何帮助深表感谢.
现在,我知道这是因为没有调用函数的开销,但是调用函数的开销真的那么重(并且值得让它内联的膨胀)?
根据我的记忆,当一个函数被调用时,比如说f(x,y),x和y被压入堆栈,堆栈指针跳转到一个空块,然后开始执行.我知道这有点过于简单了,但我错过了什么吗?一些推送和跳转来调用一个函数,真的有那么多的开销吗?
如果我忘了什么,请告诉我,谢谢!
我在理解调用者和被调用者保存的寄存器之间的区别以及何时使用什么方面遇到了一些麻烦.
我使用的是MSP430:
程序:
mov.w #0,R7
mov.w #0,R6
add.w R6,R7
inc.w R6
cmp.w R12,R6
jl l$loop
mov.w R7,R12
ret
Run Code Online (Sandbox Code Playgroud)
上面的代码是被调用者,并且在教科书示例中使用,因此它遵循惯例.R6和R7被呼叫者保存,R12被呼叫者保存.我的理解是被调用者保存的regs不是"全局的",因为在过程中改变它的值不会影响它在程序之外的值.这就是您必须在开头将新值保存到被调用者注册表中的原因.
R12,保存的来电者是"全球性的",因为缺乏更好的词汇.该程序在通话后对R12产生持久影响.
我的理解是否正确?我错过了其他的东西吗?
今天在我们的代码库中发现了以下行并且喜欢它的优雅来编写内存大小.想知道这是如何编译的几分钟.
size_t poolSize = 16 MByte;
Run Code Online (Sandbox Code Playgroud)
一个解决方案是我自己的答案.还有其他方法吗?
我想要一个128位整数,因为我想存储两个64位数的乘法结果.在gcc 4.4及以上版本中有没有这样的东西?
我有以下代码:
unsigned char x = 255;
printf("%x\n", x); // ff
unsigned char tmp = x << 7;
unsigned char y = tmp >> 7;
printf("%x\n", y); // 1
unsigned char z = (x << 7) >> 7;
printf("%x\n", z); // ff
Run Code Online (Sandbox Code Playgroud)
我会期望y并且z是一样的。但它们因是否使用中间变量而异。知道为什么会这样会很有趣。
有没有办法在 JavaScript 中获取BigInt的对数?
对于普通数字,您可以使用以下代码:
const largeNumber = 1000;
const result = Math.log(largeNumber);
Run Code Online (Sandbox Code Playgroud)
但是,我需要使用阶乘数字,可能高于 170!,因此常规数字类型不起作用。Math.log不适用于 BigInt。那么如何得到对数呢?
const largeNumber = BigInt(1000);
const result = ???
Run Code Online (Sandbox Code Playgroud) 我正在为此代码使用 g++ 10.2。没有任何人知道为什么我得到一个编译错误在过去std::views::reverse的results3?
#include <vector>
#include <ranges>
int main() {
auto values = std::vector{1,2,3,4,5,6,7,8,9,10};
auto even = [](const auto value) {
return value % 2 == 0;
};
auto square = [](const auto value) {
return value * value;
};
auto results1 = values
| std::views::filter(even)
| std::views::reverse
| std::views::take(4)
| std::views::reverse;
auto results2 = values
| std::views::transform(square)
| std::views::reverse
| std::views::take(4)
| std::views::reverse;
auto results3 = values
| std::views::filter(even)
| std::views::transform(square)
| std::views::reverse
| std::views::take(4) …Run Code Online (Sandbox Code Playgroud) 我正在寻找最快/最节省空间的方法,将 64 位寄存器减少为 32 位寄存器,仅保留 64 位寄存器的零/非零状态。
我目前适用于所有值的最佳想法是popcntq
(1c tput,主流英特尔上的 3c 延迟,5 字节代码大小):
// rax is either zero or non-zero
popcntq %rax, %rax
// eax will be zero if rax was zero, otherwise it will be non-zero
Run Code Online (Sandbox Code Playgroud)
注意:直接使用 32 位是行不通的eax:如果rax说 的2^61零/非零状态eax与 的不同rax
有没有更好的巧妙方法?
c ×4
assembly ×3
c++ ×3
bigint ×2
gcc ×2
x86-64 ×2
128-bit ×1
abi ×1
algorithm ×1
biginteger ×1
bit-shift ×1
c++20 ×1
compilation ×1
inline ×1
javascript ×1
logarithm ×1
operators ×1
optimization ×1
performance ×1
std-ranges ×1