Skip to content

Commit e782b35

Browse files
committed
Word256: Fix a bug in minus256
1 parent b2d6c97 commit e782b35

File tree

1 file changed

+21
-23
lines changed

1 file changed

+21
-23
lines changed

src/Data/WideWord/Word256.hs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -297,25 +297,16 @@ plus256 (Word256 a3 a2 a1 a0) (Word256 b3 b2 b1 b0) =
297297
{-# INLINABLE minus256 #-}
298298
minus256 :: Word256 -> Word256 -> Word256
299299
minus256 (Word256 a3 a2 a1 a0) (Word256 b3 b2 b1 b0) =
300-
Word256 s3 s2 s1 s0
300+
Word256 d3 d2 d1 d0
301301
where
302-
!(v1, s0) = subCarryDiff a0 b0
303-
!(v2, s1) =
304-
if v1 == 0
305-
then subCarryDiff a1 b1
306-
else if a1 == 0
307-
then (0xFFFFFFFFFFFFFFFF - b1, 1)
308-
else subCarryDiff (a1 - 1) b1
309-
!(v3, s2) =
310-
if v2 == 0
311-
then subCarryDiff a2 b2
312-
else if a1 == 0
313-
then (0xFFFFFFFFFFFFFFFF - b2, 1)
314-
else subCarryDiff (a2 - 1) b2
315-
!s3 =
316-
if v3 == 0
317-
then a3 - b3
318-
else (a3 - 1) - b3
302+
!(c1, d0) = subCarryDiff a0 b0
303+
!(c2a, b1a) = plusCarrySum b1 c1
304+
!(c2b, d1) = subCarryDiff a1 b1a
305+
!c2 = c2a + c2b
306+
!(c3a, b2a) = plusCarrySum b2 c2
307+
!(c3b, d2) = subCarryDiff a2 b2a
308+
!c3 = c3a + c3b
309+
!d3 = a3 - b3 - c3
319310

320311
times256 :: Word256 -> Word256 -> Word256
321312
times256 (Word256 a3 a2 a1 a0) (Word256 b3 b2 b1 b0) =
@@ -441,29 +432,36 @@ shiftR256 w@(Word256 a3 a2 a1 a0) s
441432
(a1 `shiftR` (s - 64) + a2 `shiftL` (128 - s))
442433
| s == 64 = Word256 0 a3 a2 a1
443434
| otherwise =
444-
Word256 (a3 `shiftR` s)
435+
Word256
436+
(a3 `shiftR` s)
445437
(a2 `shiftR` s + a3 `shiftL` (64 - s))
446438
(a1 `shiftR` s + a2 `shiftL` (64 - s))
447439
(a0 `shiftR` s + a1 `shiftL` (64 - s))
448440

449441
{-# INLINABLE rotateL256 #-}
450442
rotateL256 :: Word256 -> Int -> Word256
451443
rotateL256 w@(Word256 a3 a2 a1 a0) r
452-
| r < 0 = rotateL256 w (256 - (abs r `mod` 256))
444+
| r < 0 = rotateR256 w ((abs r) `mod` 256)
453445
| r == 0 = w
454446
| r >= 256 = rotateL256 w (r `mod` 256)
447+
| r >= 192 = rotateL256 (Word256 a0 a3 a2 a1) (r - 192)
448+
| r >= 128 = rotateL256 (Word256 a1 a0 a3 a2) (r - 128)
455449
| r >= 64 = rotateL256 (Word256 a2 a1 a0 a3) (r - 64)
456450
| otherwise =
457451
Word256
458-
(a3 `shiftL` r + a2 `shiftR` (64 - r)) (a2 `shiftL` r + a1 `shiftR` (64 - r))
459-
(a1 `shiftL` r + a0 `shiftR` (64 - r)) (a0 `shiftL` r + a3 `shiftR` (64 - r))
452+
(a3 `shiftL` r + a2 `shiftR` (64 - r))
453+
(a2 `shiftL` r + a1 `shiftR` (64 - r))
454+
(a1 `shiftL` r + a0 `shiftR` (64 - r))
455+
(a0 `shiftL` r + a3 `shiftR` (64 - r))
460456

461457
{-# INLINABLE rotateR256 #-}
462458
rotateR256 :: Word256 -> Int -> Word256
463459
rotateR256 w@(Word256 a3 a2 a1 a0) r
464-
| r < 0 = rotateR256 w (256 - (abs r `mod` 256))
460+
| r < 0 = rotateL256 w ((abs r) `mod` 256)
465461
| r == 0 = w
466462
| r >= 256 = rotateR256 w (r `mod` 256)
463+
| r >= 192 = rotateR256 (Word256 a2 a1 a0 a3) (r - 192)
464+
| r >= 128 = rotateR256 (Word256 a1 a0 a3 a2) (r - 128)
467465
| r >= 64 = rotateR256 (Word256 a0 a3 a2 a1) (r - 64)
468466
| otherwise =
469467
Word256

0 commit comments

Comments
 (0)