最佳性能加法模 2^32 实现
Best performance addition modulo 2^32 implemetation
我正在研究 SHA-256 实现,我已经到了需要对无符号数进行加法模 2^32
的地步。
我的第一个想法是使用溢出行为:
uint32_t a = ...;
uint32_t b = ...;
uint32_t c = a + b;
但我有两个顾虑:
- 溢出是否总是定义的行为,如果我可以相信它会像
模加法
sizeof(_operand_)
如果两个操作数和结果
变量是同一类型?
- 如何消除编译器警告
关于可能的溢出,正确的方法?
我的第二个想法是使用更长类型的变量来实现它:
uint32_t a = ...;
uint32_t b = ...;
uint64_t a_64 = a;
uint64_t b_64 = b;
uint64_t c_64 = a_64 + b_64;
uint32_t c = uint32_t(c_64 & 0xFFFFFFFF);
但是这个解决方案需要几个额外的变量、它们的初始化和额外的按位与操作。
在 C
编程原则和性能方面,这些实现中的哪一个(如果有)是正确的?如果其中 none 个,正确的实施是什么?
uint32_t
是模 2^32 类型。它不仅是一种范围至少达到 2^32-1 的类型,而且根据硬件要求可能更多;那将是 uint32least_t
.
所以,uint32_t
上的加法总是模加法,不适合需要溢出概念的运算。最好的解决方案就是 a+b
.
我正在研究 SHA-256 实现,我已经到了需要对无符号数进行加法模 2^32
的地步。
我的第一个想法是使用溢出行为:
uint32_t a = ...;
uint32_t b = ...;
uint32_t c = a + b;
但我有两个顾虑:
- 溢出是否总是定义的行为,如果我可以相信它会像
模加法
sizeof(_operand_)
如果两个操作数和结果 变量是同一类型? - 如何消除编译器警告 关于可能的溢出,正确的方法?
我的第二个想法是使用更长类型的变量来实现它:
uint32_t a = ...;
uint32_t b = ...;
uint64_t a_64 = a;
uint64_t b_64 = b;
uint64_t c_64 = a_64 + b_64;
uint32_t c = uint32_t(c_64 & 0xFFFFFFFF);
但是这个解决方案需要几个额外的变量、它们的初始化和额外的按位与操作。
在 C
编程原则和性能方面,这些实现中的哪一个(如果有)是正确的?如果其中 none 个,正确的实施是什么?
uint32_t
是模 2^32 类型。它不仅是一种范围至少达到 2^32-1 的类型,而且根据硬件要求可能更多;那将是 uint32least_t
.
所以,uint32_t
上的加法总是模加法,不适合需要溢出概念的运算。最好的解决方案就是 a+b
.