bytevector-s16-ref, bytevector-s32-ref, bytevector-s64-ref, bytevector-u16-ref, bytevector-u32-ref, bytevector-u64-ref, bytevector-ieee-double-ref, bytevector-ieee-single-ref,bytevector-s16-native-ref, bytevector-s32-native-ref, bytevector-s64-native-ref, bytevector-u16-native-ref, bytevector-u32-native-ref, bytevector-u64-native-ref, bytevector-ieee-single-native-ref, bytevector-ieee-double-native-ref - read from a bytevector


(import (rnrs))                     ;R6RS
(import (rnrs bytevectors))         ;R6RS


(bytevector-s16-ref bytevector k endianness)
(bytevector-s32-ref bytevector k endianness)
(bytevector-s64-ref bytevector k endianness)

(bytevector-u16-ref bytevector k endianness)
(bytevector-u32-ref bytevector k endianness)
(bytevector-u64-ref bytevector k endianness)

(bytevector-ieee-double-ref bytevector k endianness)
(bytevector-ieee-single-ref bytevector k endianness)

(bytevector-s16-native-ref bytevector k)
(bytevector-s32-native-ref bytevector k)
(bytevector-s64-native-ref bytevector k)

(bytevector-u16-native-ref bytevector k)
(bytevector-u32-native-ref bytevector k)
(bytevector-u64-native-ref bytevector k)

(bytevector-ieee-single-native-ref bytevector k)
(bytevector-ieee-double-native-ref bytevector k)


These procedures read two or more bytes from bytevector, starting from the index k, and return them as an exact integer object. The bytes are interpreted according to a data type and endianness. The data type is one of the following:
signed 16-bit integer
signed 32-bit integer
signed 64-bit integer
unsigned 16-bit integer
unsigned 32-bit integer
unsigned 64-bit integer
IEEE-754 double-precision float (binary64)
IEEE-754 single-precision float (binary32)

The signed variants use the two's complement representation.

The endianness is normally one of the following symbols:

Big endian. The more significant bytes come before the less significant bytes.
Little endian. The less significant bytes come before the more significant bytes.

The -native variants use the machine's native endianness and furthermore impose an alignment requirement: the index k must be evenly divisible by the data type size (2, 4 or 8). Such an access is said to be aligned, as opposed to an unaligned access.

The number of bytes n used depends on the data type and is either two, four or eight (corresponding to 16, 32 or 64 bits). The bytevector must be at least k+n bytes in length.

Unlike the equivalent operation in e.g. C, the index is not multiplied by the element size.


Loko Scheme
Hardware alignment checking is used to speed up the native procedures.


Returns a single exact integer object.


(define b
  #vu8(#xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFF
       #xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFD))

(bytevector-u16-ref b 14 (endianness little))
          => 65023          ;#xFDFF

(bytevector-s16-ref b 14 (endianness little))
          => -513           ;#x-201

(bytevector-u16-ref b 14 (endianness big))
          => 65533          ;#xFFFD

(bytevector-s16-ref b 14 (endianness big))
          => -3

(bytevector-u32-ref b 12 (endianness little))
          => 4261412863     ;#xFDFFFFFF

(bytevector-s32-ref b 12 (endianness little))
          => -33554433      ;#x-2000001

(bytevector-u32-ref b 12 (endianness big))
          => 4294967293     ;#xFFFFFFFD

(bytevector-s32-ref b 12 (endianness big))
          => -3

(bytevector-u64-ref b 8 (endianness little))
          => 18302628885633695743    ;#xFDFFFFFFFFFFFFFF

(bytevector-s64-ref b 8 (endianness little))
          => -144115188075855873     ;#x-200000000000001

(bytevector-u64-ref b 8 (endianness big))
          => 18446744073709551613    ;#xFFFFFFFFFFFFFFFD

(bytevector-s64-ref b 8 (endianness big))
          => -3

;; Native endianness can be little, big or something else.
;; R6RS leaves room for other native endianness choices.
(bytevector-u32-native-ref b 12)
          => unspecified


Applications use these procedures when parsing data structures or when storing data in bytevectors as backing for custom data types. In some cases these procedures are cumbersome and packages like struct-pack or scheme-bytestructures can help reduce the amount of written code and help to automatically manage indices.


These procedures provide accessors for the most common scalar data types (larger than a byte) that can be stored in bytevectors. The native procedures match what is provided by modern hardware, so they are potentially more efficient than the other procedures.

The native procedures check that the index is aligned. This is because hardware generally does not handle unaligned accesses the same way as aligned accesses. An unaligned access is slower and more complicated than an aligned access for several reasons that are outside the scope of this document to explain.


Except for the native variants, and differences in performance, these procedures work the same on all machines and in all implementations.

Careless use of the native procedures can make a program unportable, because the program's handling of bytes will depend on the particular machine it is running on. Most computers today are little-endian, but some big-endian machines are still being made. Except for this difference, any portability concerns at lower machine layers are abstracted away.


This procedure can raise exceptions with the following condition types:
&assertion (R6RS)
The wrong number of arguments was passed or an argument was outside its domain. An out-of-range access was attempted. The index k was not a multiple of the access size (in the case of the native variants).


make-bytevector(3scm), bytevector-u8-ref(3scm), endianness(7scm), native-endianness(3scm)




These procedures are based on SRFI-74.


This page is part of the scheme-manpages project. It includes materials from the RnRS documents. More information can be found at


An implementation written in C should not perform unaligned accesses towards the underlying memory, because the behavior is undefined. It will probably work on x86(-64), but it is still undefined and will break on other machines.

Markup created by unroff 1.0sc,    March 04, 2023.