Add with carry on Word8

给你一囗甜甜゛ 提交于 2019-12-10 20:30:03

问题


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?


回答1:


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#



回答2:


A way to do this is:

addWithCarry :: Word8 -> Word8 -> (Word8, Bool)
addWithCarry x y = (z, carry)
  where z = x + y
        carry = z < x


来源:https://stackoverflow.com/questions/27204425/add-with-carry-on-word8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!