问题描述
我找不到一个函数 addWithCarry :: Word8 - > Word8 - > (Word8,Bool)
已经在 base
中定义。记录为关心进行的唯一功能似乎是 addIntC#
在 GHC.Prim
中,但它似乎永远不会被推送通过不同的抽象层。
通过测试输出值是否在范围内,我显然可以推出我自己的产品,实际上我正在做的是,而是重复使用已经定义好的(可能更有效)。
是否有这样的事情?
如果你看,你会发现所有事情都是通过转换为 Word#
取消装箱值并对其执行操作完成的,然后缩小到8位值。我怀疑,比较 Word#
值会更有效率,所以我实现了这样的事情。它的(我发现它比StackOverflow更容易阅读)。
请注意,它包含测试套件和标准基准。在我的系统中,所有各种测试对于盒装版本(user5402的实现)需要约31ns,对于primops版本,约需24ns。
上述lpaste中的重要功能 primops
,即:
primops :: Word8 - > Word8 - > (W8#x#)(W8#y#)=
(W8#(narrow8Word#z#),isTrue#(gtWord#z#255 ##))$ b(Word8,Bool)
primops $ b其中
z#= plusWord#x#y#
I can't find a function addWithCarry :: Word8 -> Word8 -> (Word8, Bool)
already defined in base
. The only function documented as caring about carries seems to be addIntC#
in GHC.Prim
but it seems to never be pushed upwards through the various abstraction layers.
I could obviously roll out my own by testing whether the output value is in range and it's in fact what I am currently doing but I'd rather reuse an (potentially more efficient) already defined one.
Is there such a thing?
If you look at the source for Word8's Num instance, you'll see that everything is done by converting to a Word#
unboxed value and performing operations on that, and then narrowing down to a 8-bit value. I suspected that doing comparison on that Word#
value would be more efficient, so I implemented such a thing. It's available on lpaste (which I find easier to read than StackOverflow).
Note that it includes both a test suite and Criterion benchmark. On my system, all of the various tests take ~31ns for the boxed version (user5402's implementation) and ~24ns for the primops versions.
The important function from the lpaste above is primops
, which is:
primops :: Word8 -> Word8 -> (Word8, Bool)
primops (W8# x#) (W8# y#) =
(W8# (narrow8Word# z#), isTrue# (gtWord# z# 255##))
where
z# = plusWord# x# y#
这篇关于加上随身携带的Word8的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!