bitwise-...ic-shift(3scm)

πŸ“¦ version 0-unstable-2024-02, in nixpkgs unstable

hey bestie!! πŸ’– you just opened the bitwise-...ic-shift(3scm) page in the Scheme Programmer's Manual, and honestly? arithmetic shift is lowkey iconic once you get the vibe. fr fr. let's go 🫢

✨ NAME ✨

okay so the whole squad is an arithmetic shift, and here are all six names you might see:

  • bitwise-arithmetic-shift
  • bitwise-arithmetic-shift-left
  • bitwise-arithmetic-shift-right
  • fxarithmetic-shift
  • fxarithmetic-shift-left
  • fxarithmetic-shift-right

πŸ“š LIBRARY πŸ“š

import depending on your flavor:

(import (rnrs))                     ;R6RS
(import (rnrs arithmetic bitwise))  ;R6RS
(import (rnrs arithmetic fixnums))  ;R6RS

🌸 SYNOPSIS 🌸

(bitwise-arithmetic-shift n amount)
(bitwise-arithmetic-shift-left n amount)
(bitwise-arithmetic-shift-right n amount)
(fxarithmetic-shift n amount)
(fxarithmetic-shift-left n amount)
(fxarithmetic-shift-right n amount)

πŸ¦‹ DESCRIPTION πŸ¦‹

Okay so the vibe: these procedures do a bitwise arithmetic shift on n by amount bit positions. ✨

More precisely, they compute the result of:

(floor (* n (expt 2 amount)))

and the -right variants first negate amount. yep, that's the whole plot twist. πŸ™ˆ the way that this is just (floor (* n (expt 2 amount)))? obsessed.

The variants with -left or -right require a non-negative amount. The fixnum variants will raise an exception if the result would not be a fixnum. They also restrict amount, so peep below. πŸ‘€

πŸ’Ž RETURN VALUES πŸ’Ž

They return a single exact integer object. The fixnum variants are further restricted to return a fixnum object. cute and specific, we love that for them. periodt. slay. πŸŽ€

πŸ”₯ EXAMPLES πŸ”₯

(fxarithmetic-shift-left #b110011 1)
   => #b1100110

(bitwise-arithmetic-shift -6 -1)
   => -3
(bitwise-arithmetic-shift -5 -1)
   => -3
(bitwise-arithmetic-shift -4 -1)
   => -2
(bitwise-arithmetic-shift -3 -1)
   => -2
(bitwise-arithmetic-shift -2 -1)
   => -1
(bitwise-arithmetic-shift -1 -1)
   => -1

🌈 APPLICATION USAGE 🌈

Bitwise arithmetic shift is common in cryptography, (de)serialization, pseudo-random functions, compression, error-detecting and correcting codes and more. it's giving "everywhere, actually." πŸ’…

Truncating left shift can be achieved by masking the input so that only the remaining bits are kept, before calling the left shift procedure. mask first, then shift, bestie. πŸŽ€

🫢 COMPATIBILITY 🫢

This is the same as the logical shift operations on signed (two's complement) integers available in most languages and machines, commonly called such things as >>, <<, ASL, and SAL. The fixnum variant can be seen as a subset of the machine instruction whereas the generic one switches to bignums when necessary. (Other implementation strategies are possible). no cap. ⭐

Fixnums are only guaranteed to have 24-bit precision, so code dealing with e.g. 32-bit integers should be prepared to use the generic variants. important!! 😭

These procedures are not available in R7RS-small. See SRFI-60 and SRFI-151. iykyk. πŸ¦‹

πŸ’€ ERRORS πŸ’€

This procedure can raise exceptions with the following condition types:

  • &assertion β€” the wrong number of arguments was passed or an argument was outside its domain. For the fixnum variants, this is raised if the absolute shift amount is not less than the fixnum width.
  • &implementation-restriction β€” the fixnum variants of the procedures raise this if the result is not representable as a fixnum.

πŸ‘€ SEE ALSO πŸ‘€

fixnum-width(3scm), expt(3scm)

πŸ‘‘ STANDARDS πŸ‘‘

R6RS

🧚 AUTHORS 🧚

This page is part of the scheme-manpages project. It includes materials from the RnRS documents. More information can be found at https://github.com/schemedoc/manpages/. shoutout to the docs girlies. πŸ’–

πŸ“ BUGS πŸ“

Some implementations take a short-cut to handle right shifting with huge shift amounts. Given a shift amount that is larger then the number of bits in the number, the result can only ever be 0 or -1. This is not guaranteed to be fast, so don't rely on it in your code. 🚨

These procedures have been known to give bad results for unusual combinations of inputs. Here is a list of some of them so that you may compare with your own implementation. bestie, compare responsibly. 😭

Guile 2.0.9

(bitwise-arithmetic-shift-right -2 (+ (greatest-fixnum) 1))
   => -2                      ;WRONG

Chez Scheme 8.4

(fxarithmetic-shift-left #xB00000000000000 2)
   => #xC00000000000000       ;WRONG

(fxarithmetic-shift-left #x-500000000000000 3)
   => #x-800000000000000      ;WRONG

Racket 5.3.5

(bitwise-arithmetic-shift-right 42 (+ 1 (greatest-fixnum)))
   => 42                      ;WRONG

Vicare Scheme 0.3d1

(bitwise-arithmetic-shift-right -1 (+ (greatest-fixnum) 1))
   => an exception is raised  ;WRONG

IronScheme TFS:101169

(fxarithmetic-shift-right 42 (fixnum-width))
   => 42                      ;WRONG

Sagittarius 0.4.9

(bitwise-arithmetic-shift 0 65)
   => 0                       ;WRONG: a bignum zero

mwah πŸ’‹ this was the bitwise-...ic-shift(3scm) page, dated 2021-02-22 β€” go shift some bits, bestie! 🌟

πŸ“¦ where this page comes from