Variable-length quantity: Difference between revisions

Added FreeBASIC
(→‎{{header|Haskell}}: Added type signatures, slight tidying)
(Added FreeBASIC)
 
(40 intermediate revisions by 23 users not shown)
Line 3:
Implement some operations on [[wp:Variable-length quantity|variable-length quantities]], at least including conversions from a normal number in the language to the binary representation of the variable-length quantity for that number, and ''vice versa''. Any variants are acceptable.
 
 
'''Task :''' With above operations,
;Task:
With above operations,
*convert these two numbers 0x200000 (2097152 in decimal) and 0x1fffff (2097151 in decimal) into sequences of octets (an eight-bit byte);
*display these sequences of octets;
*convert these sequences of octets back to numbers, and check that they are equal to original numbers.
<br><br>
 
=={{header|11l}}==
{{trans|C++}}
 
<syntaxhighlight lang="11l">F to_str(v)
R ‘[ ’v.map(n -> hex(n).lowercase().zfill(2)).join(‘ ’)‘ ]’
 
F to_seq(UInt64 x)
V i = 0
L(ii) (9.<0).step(-1)
I x [&] (UInt64(127) << ii * 7) != 0
i = ii
L.break
 
[Byte] out
L(j) 0 .. i
out [+]= ((x >> ((i - j) * 7)) [&] 127) [|] 128
 
out[i] (+)= 128
R out
 
F from_seq(seq)
UInt64 r = 0
 
L(b) seq
r = (r << 7) [|] (b [&] 127)
 
R r
 
L(x) [UInt64(7'F), 40'00, 0, 003F'FFFE, 001F'FFFF, 0020'0000, 3311'A123'4DF3'1413]
V s = to_seq(x)
print(‘seq from ’hex(x).lowercase()‘ ’to_str(s)‘ back: ’hex(from_seq(s)).lowercase())</syntaxhighlight>
 
{{out}}
<pre>
seq from 7f [ 7f ] back: 7f
seq from 4000 [ 81 80 00 ] back: 4000
seq from 0 [ 00 ] back: 0
seq from 3ffffe [ 81 ff ff 7e ] back: 3ffffe
seq from 1fffff [ ff ff 7f ] back: 1fffff
seq from 200000 [ 81 80 80 00 ] back: 200000
seq from 3311a1234df31413 [ b3 88 e8 a4 b4 ef cc a8 13 ] back: 3311a1234df31413
</pre>
 
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Containers.Vectors;
with Ada.Text_IO;
with Ada.Unchecked_Conversion;
Line 101 ⟶ 147:
Nat_IO.Put (To_Int (Test), 10, 16); Ada.Text_IO.Put (" = ");
Print (Test);
end VLQ;</langsyntaxhighlight>
 
Output:
Line 110 ⟶ 156:
16#1FFFFF# = :16#FF#:16#FF#:16#7F#
16#200000# = :16#81#:16#80#:16#80#: 16#0#</pre>
 
=={{header|BASIC}}==
==={{header|ANSI BASIC}}===
{{works with|Decimal BASIC}}
<syntaxhighlight lang="basic">INPUT s$
LET s$ = LTRIM$(RTRIM$(s$))
LET v = 0
FOR i = 1 TO LEN(s$)
LET c$ = s$(i:i)
LET k = POS("0123456789abcdef", c$)
IF k > 0 THEN LET v = v*16 + k - 1
NEXT i
PRINT "S= ";s$, "V=";v
! Convert back to hex
LET hex$ ="0123456789abcdef"
LET hs$=" "
FOR i = LEN(hs$) TO 1 STEP -1
IF v = 0 THEN EXIT FOR
LET d = MOD(v, 16) + 1
LET hs$(i:i) = hex$(d:d)
LET v = INT(v/16)
NEXT i
PRINT hs$
END</syntaxhighlight>
{{out}}
<pre>
S= 200000 V= 2097152
200000
S= 1fffff V= 2097151
1fffff
</pre>
 
==={{header|FreeBASIC}}===
{{trans|Wren}}
<syntaxhighlight lang="vbnet">Sub toOctets(n As Integer, octets() As Integer)
Dim As String s = Bin(n)
Dim As Integer le = Len(s)
Dim As Integer r = le Mod 7
Dim As Integer d = le \ 7
If (r > 0) Then
d += 1
s = Right("0000000" & s, 7 * d)
End If
For i As Integer = 0 To d - 2
Redim Preserve octets(i+1) As Integer
octets(i) = Val("&B1" & Mid(s, i * 7 + 1, 7))
Next i
octets(d - 1) = Val("&B0" & Mid(s, (d - 1) * 7 + 1, 7))
End Sub
 
Function fromOctets(octets() As Integer) As Integer
Dim As String s = ""
For i As Integer = 0 To Ubound(octets)
s &= Right("0000000" & Bin(octets(i)), 7)
Next i
Return Val("&B" & s)
End Function
 
Dim As Integer tests(1) = {2097152, 2097151}
Dim As Integer i
For i = 0 To Ubound(tests)
Dim As Integer octets()
toOctets(tests(i), octets())
Dim As String display = ""
For j As Integer = 0 To Ubound(octets)
display &= "0x" & Hex(octets(j), 2) & " "
Next j
Print tests(i); " -> "; display; "-> "; fromOctets(octets())
Next i
 
Sleep</syntaxhighlight>
{{out}}
<pre> 2097152 -> 0x81 0x80 0x80 0x00 -> 2097152
2097151 -> 0xFF 0xFF 0x7F -> 2097151</pre>
 
==={{header|Visual Basic .NET}}===
{{trans|C#}}
<syntaxhighlight lang="vbnet">Module Module1
 
Function ToVlq(v As ULong) As ULong
Dim array(8) As Byte
Dim buffer = ToVlqCollection(v).SkipWhile(Function(b) b = 0).Reverse().ToArray
buffer.CopyTo(array, 0)
Return BitConverter.ToUInt64(array, 0)
End Function
 
Function FromVlq(v As ULong) As ULong
Dim collection = BitConverter.GetBytes(v).Reverse()
Return FromVlqCollection(collection)
End Function
 
Iterator Function ToVlqCollection(v As ULong) As IEnumerable(Of Byte)
If v > Math.Pow(2, 56) Then
Throw New OverflowException("Integer exceeds max value.")
End If
 
Dim index = 7
Dim significantBitReached = False
Dim mask = &H7FUL << (index * 7)
While index >= 0
Dim buffer = mask And v
If buffer > 0 OrElse significantBitReached Then
significantBitReached = True
buffer >>= index * 7
If index > 0 Then
buffer = buffer Or &H80
End If
Yield buffer
End If
mask >>= 7
index -= 1
End While
End Function
 
Function FromVlqCollection(vlq As IEnumerable(Of Byte)) As ULong
Dim v = 0UL
Dim significantBitReached = False
 
Using enumerator = vlq.GetEnumerator
Dim index = 0
While enumerator.MoveNext
Dim buffer = enumerator.Current
If buffer > 0 OrElse significantBitReached Then
significantBitReached = True
v <<= 7
v = v Or (buffer And &H7FUL)
End If
 
index += 1
If index = 8 OrElse (significantBitReached AndAlso (buffer And &H80) <> &H80) Then
Exit While
End If
End While
End Using
 
Return v
End Function
 
Sub Main()
Dim values = {&H7FUL << 7 * 7, &H80, &H2000, &H3FFF, &H4000, &H200000, &H1FFFFF}
For Each original In values
Console.WriteLine("Original: 0x{0:X}", original)
 
REM collection
Dim seq = ToVlqCollection(original)
Console.WriteLine("Sequence: 0x{0}", seq.Select(Function(b) b.ToString("X2")).Aggregate(Function(a, b) String.Concat(a, b)))
 
Dim decoded = FromVlqCollection(seq)
Console.WriteLine("Decoded: 0x{0:X}", decoded)
 
REM ints
Dim encoded = ToVlq(original)
Console.WriteLine("Encoded: 0x{0:X}", encoded)
 
decoded = FromVlq(encoded)
Console.WriteLine("Decoded: 0x{0:X}", decoded)
 
Console.WriteLine()
Next
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>Original: 0xFE000000000000
Sequence: 0xFF80808080808000
Decoded: 0xFE000000000000
Encoded: 0xFF80808080808000
Decoded: 0xFE000000000000
 
Original: 0x80
Sequence: 0x8100
Decoded: 0x80
Encoded: 0x8100
Decoded: 0x80
 
Original: 0x2000
Sequence: 0xC000
Decoded: 0x2000
Encoded: 0xC000
Decoded: 0x2000
 
Original: 0x3FFF
Sequence: 0xFF7F
Decoded: 0x3FFF
Encoded: 0xFF7F
Decoded: 0x3FFF
 
Original: 0x4000
Sequence: 0x818000
Decoded: 0x4000
Encoded: 0x818000
Decoded: 0x4000
 
Original: 0x200000
Sequence: 0x81808000
Decoded: 0x200000
Encoded: 0x81808000
Decoded: 0x200000
 
Original: 0x1FFFFF
Sequence: 0xFFFF7F
Decoded: 0x1FFFFF
Encoded: 0xFFFF7F
Decoded: 0x1FFFFF</pre>
 
=={{header|Bracmat}}==
Bracmat has no native octet array type. Luckily, the only octet that possibly can be zero in a VLQ is the last octet. Therefore a solitary VLQ can be expressed as a Bracmat string, which, just as a C string, is null terminated. If the last byte of the VLQ string has the high bit set, we know that the last octet contained 0-bits only. A problem is of course that VLQ's probably are meant to be concatenizable. With null bytes missing, this is no option for the VLQ's generated by this solution.
<langsyntaxhighlight lang="bracmat">( ( VLQ
= b07 b8 vlq
. 0:?b8
Line 168 ⟶ 420:
& test$82
& test$894E410E0A
);</langsyntaxhighlight>
Output:
<pre>input: 200000
Line 204 ⟶ 456:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdint.h>
 
Line 246 ⟶ 498:
 
return 0;
}</langsyntaxhighlight>output<syntaxhighlight lang="text">seq from 7f: [ 7f ] back: 7f
seq from 4000: [ 81 80 00 ] back: 4000
seq from 0: [ 00 ] back: 0
Line 252 ⟶ 504:
seq from 1fffff: [ ff ff 7f ] back: 1fffff
seq from 200000: [ 81 80 80 00 ] back: 200000
seq from 3311a1234df31413: [ b3 88 e8 a4 b4 ef cc a8 13 ] back: 3311a1234df31413</langsyntaxhighlight>
 
=={{header|C++}}==
{{trans|C}}
<syntaxhighlight lang="cpp">#include <iomanip>
#include <iostream>
#include <vector>
 
std::ostream &operator<<(std::ostream &os, const std::vector<uint8_t> &v) {
auto it = v.cbegin();
auto end = v.cend();
 
os << "[ ";
if (it != end) {
os << std::setfill('0') << std::setw(2) << (uint32_t)*it;
it = std::next(it);
}
while (it != end) {
os << ' ' << std::setfill('0') << std::setw(2) << (uint32_t)*it;
it = std::next(it);
}
return os << " ]";
}
 
std::vector<uint8_t> to_seq(uint64_t x) {
int i;
for (i = 9; i > 0; i--) {
if (x & 127ULL << i * 7) {
break;
}
}
 
std::vector<uint8_t> out;
for (int j = 0; j <= i; j++) {
out.push_back(((x >> ((i - j) * 7)) & 127) | 128);
}
out[i] ^= 128;
return out;
}
 
uint64_t from_seq(const std::vector<uint8_t> &seq) {
uint64_t r = 0;
 
for (auto b : seq) {
r = (r << 7) | (b & 127);
}
 
return r;
}
 
int main() {
std::vector<uint64_t> src{ 0x7f, 0x4000, 0, 0x3ffffe, 0x1fffff, 0x200000, 0x3311a1234df31413ULL };
 
for (auto x : src) {
auto s = to_seq(x);
std::cout << std::hex;
std::cout << "seq from " << x << ' ' << s << " back: " << from_seq(s) << '\n';
std::cout << std::dec;
}
 
return 0;
}</syntaxhighlight>
{{out}}
<pre>seq from 7f [ 7f ] back: 7f
seq from 4000 [ 81 80 00 ] back: 4000
seq from 0 [ 00 ] back: 0
seq from 3ffffe [ 81 ff ff 7e ] back: 3ffffe
seq from 1fffff [ ff ff 7f ] back: 1fffff
seq from 200000 [ 81 80 80 00 ] back: 200000
seq from 3311a1234df31413 [ b3 88 e8 a4 b4 ef cc a8 13 ] back: 3311a1234df31413</pre>
 
=={{header|C sharp|C#}}==
For methods involving a '''BinaryReader''' or '''BinaryWriter''' please refer to [http://rosettacode.org/wiki/User:Shimmy/Variable-length_quantity this] page.
<langsyntaxhighlight lang="csharp">namespace Vlq
{
using System;
Line 359 ⟶ 680:
}
}
}</langsyntaxhighlight>output<syntaxhighlight lang="text">Original: 0xFE000000000000
Sequence: 0xFF80808080808000
Decoded: 0xFE000000000000
Line 401 ⟶ 722:
Decoded: 0x1FFFFF
 
Press any key to continue...</langsyntaxhighlight>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
 
sub VLQEncode(number: uint32, buf: [uint8]) is
var step := number;
while step > 0 loop
step := step >> 7;
buf := @next buf;
end loop;
var mark: uint8 := 0;
while number > 0 loop
buf := @prev buf;
[buf] := mark | (number as uint8 & 0x7F);
mark := 0x80;
number := number >> 7;
end loop;
end sub;
 
sub VLQDecode(buf: [uint8]): (result: uint32) is
result := 0;
loop
var byte := [buf];
buf := @next buf;
result := (result << 7) | (byte & 0x7F) as uint32;
if byte & 0x80 == 0 then
return;
end if;
end loop;
end sub;
 
sub VLQPrint(buf: [uint8]) is
loop
print_hex_i8([buf]);
if [buf] & 0x80 == 0 then
break;
end if;
buf := @next buf;
end loop;
end sub;
 
sub VLQTest(value: uint32) is
var buf: uint8[8];
print("Input: ");
print_hex_i32(value);
print_nl();
print("Encoded: ");
VLQEncode(value, &buf[0]);
VLQPrint(&buf[0]);
print_nl();
print("Decoded: ");
value := VLQDecode(&buf[0]);
print_hex_i32(value);
print_nl();
end sub;
 
VLQTest(0x200000);
print_nl();
VLQTest(0x1FFFFF);
print_nl();</syntaxhighlight>
{{out}}
<pre>Input: 00200000
Encoded: 81808000
Decoded: 00200000
 
Input: 001fffff
Encoded: ffff7f
Decoded: 001fffff</pre>
 
=={{header|D}}==
This implements a Variable-length Quantity struct for an ulong integer.
<langsyntaxhighlight lang="d">import std.stdio, std.string, std.file, std.algorithm;
 
/// Variable length quantity (unsigned long, max 63-bit).
Line 489 ⟶ 883:
foreach (immutable i, immutable v; VLQ.split(buf))
writefln("%d:%8x = %s", i + 1, v, VLQ(v));
}</langsyntaxhighlight>
{{out}}
<pre>a: 7f = (7F)
Line 503 ⟶ 897:
2: 1fffff = (FF:FF:7F)
3: 200000 = (81:80:80:00)</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
 
 
 
function NumberToVLQ(Num: int64): string;
{Convert Num to Variable-Length Quantity VLQ Octets (bytes)}
{Octet = 7-bit data and MSB indicating the last data item = 0 }
{Note: String are being used as byte-array because they are easy}
var I: integer;
var T: byte;
var BA: string;
begin
Result:='';
BA:='';
{Get array of octets}
while Num>0 do
begin
BA:=BA+char($7F and Num);
Num:=Num shr 7;
end;
{Reverse data and flag more data is coming}
Result:='';
for I:=Length(BA) downto 1 do
begin
T:=Byte(BA[I]);
if I<>1 then T:=T or $80;
Result:=Result+char(T);
end;
end;
 
 
function VLQToNumber(VLQ: string): int64;
{Convert Variable-Length Quantity VLQ Octets (bytes) to numbers}
{Octet = 7-bit data and MSB indicating the last data item = 0 }
{Note: String are being used as byte-array because they are easy}
var I: integer;
var T: byte;
var BA: string;
begin
Result:=0;
for I:=1 to Length(VLQ) do
Result:=(Result shl 7) or (Byte(VLQ[I]) and $7F);
end;
 
 
 
function VLQToString(VLQ: string): string;
{Convert VLQ to string of hex numbers}
var I: integer;
begin
Result:='(';
for I:=1 to Length(VLQ) do
begin
if I>1 then Result:=Result+', ';
Result:=Result+IntToHex(byte(VLQ[I]),2);
end;
Result:=Result+')';
end;
 
 
 
procedure ShowVLQ(Memo: TMemo; Num: int64);
var VLQ: string;
var I: int64;
var S: string;
begin
VLQ:=NumberToVLQ(Num);
S:=VLQToString(VLQ);
I:=VLQToNumber(VLQ);
Memo.Lines.Add('Original Number: '+Format('%x',[Num]));
Memo.Lines.Add('Converted to VLQ: '+Format('%s',[S]));
Memo.Lines.Add('Back to Original: '+Format('%x',[I]));
Memo.Lines.Add('');
end;
 
const Num1 = $0;
const Num2 = $7F;
const Num3 = $4000;
const Num4 = $1FFFFF;
const Num5 = $200000;
const Num6 = $3FFFFE;
const Num7 = $3311A1234DF31413;
 
 
 
procedure VariableLengthOctets(Memo: TMemo);
begin
ShowVLQ(Memo, Num1);
ShowVLQ(Memo, Num2);
ShowVLQ(Memo, Num3);
ShowVLQ(Memo, Num4);
ShowVLQ(Memo, Num5);
ShowVLQ(Memo, Num6);
ShowVLQ(Memo, Num7);
end;
 
 
 
 
</syntaxhighlight>
{{out}}
<pre>
Original Number: 0
Converted to VLQ: ()
Back to Original: 0
 
Original Number: 7F
Converted to VLQ: (7F)
Back to Original: 7F
 
Original Number: 4000
Converted to VLQ: (81, 80, 00)
Back to Original: 4000
 
Original Number: 1FFFFF
Converted to VLQ: (FF, FF, 7F)
Back to Original: 1FFFFF
 
Original Number: 200000
Converted to VLQ: (81, 80, 80, 00)
Back to Original: 200000
 
Original Number: 3FFFFE
Converted to VLQ: (81, FF, FF, 7E)
Back to Original: 3FFFFE
 
Original Number: 3311A1234DF31413
Converted to VLQ: (B3, 88, E8, A4, B4, EF, CC, A8, 13)
Back to Original: 3311A1234DF31413
 
Elapsed Time: 42.717 ms.
</pre>
 
 
=={{header|Erlang}}==
Line 518 ⟶ 1,051:
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">function vlq_encode(integer n)
sequence s
s = {}
Line 558 ⟶ 1,091:
s = vlq_encode(testNumbers[i])
printf(1, "#%02x -> %s -> #%02x\n", {testNumbers[i], svlg(s), vlq_decode(s)})
end for</langsyntaxhighlight>
 
Output:
Line 567 ⟶ 1,100:
#80 -> #81:#00 -> #80
</pre>
 
=={{header|Go}}==
Go has an implementation of variable length quantities in the standard library.
<langsyntaxhighlight lang="go">package main
 
import (
Line 584 ⟶ 1,118:
fmt.Println(x, "decoded")
}
}</langsyntaxhighlight>
Output required by task:
<pre>
Line 616 ⟶ 1,150:
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">final RADIX = 7
final MASK = 2**RADIX - 1
Line 631 ⟶ 1,165:
(n << RADIX) + ((int)(octet) & MASK)
}
}</langsyntaxhighlight>
 
Test (samples borrowed from [[Java]] example):
<langsyntaxhighlight lang="groovy">def testNumbers = [ 0x200000, 0x1fffff, 1, 127, 128, 589723405834L ]
testNumbers.each { a ->
Line 641 ⟶ 1,175:
def a1 = deoctetify(octets)
assert a1 == a
}</langsyntaxhighlight>
 
Output:
Line 653 ⟶ 1,187:
=={{header|Haskell}}==
 
<langsyntaxhighlight Haskelllang="haskell">import Numeric (readOct, showOct)
import Data.MonoidList ((<>)intercalate)
 
to :: Int -> String
Line 665 ⟶ 1,199:
main =
mapM_
(putStrLn . (pure (<>) <*> to <*> ((" <-> " <>) . show . from . to)))
intercalate " <-> " . (pure (:) <*> to <*> (return . show . from . to)))
[2097152, 2097151]</lang>
[2097152, 2097151]</syntaxhighlight>
 
Homemade Version:
 
<langsyntaxhighlight Haskelllang="haskell">import Data.List (intercalate)
 
baseto :: Int -> Int -> [Int]
baseto _ 0 = 8[]
to base i = to base q <> [r]
where
(q, r) = quotRem i base
 
tofrom :: Int -> [Int] -> Int
from base = foldl1 ((+) . (base *))
to 0 = []
to i = to (div i base) ++ [mod i base]
 
from :: [Int] -> Int
from = foldl1 (\x y -> x * base + y)
 
--------------------------- TEST ---------------------------
main :: IO ()
main =
Line 687 ⟶ 1,223:
(putStrLn .
intercalate " <-> " .
(((:) . concatMap(=<<) show . totoBase) <*> (return . show . fromfromBase . totoBase)))
[2097152, 2097151]
where
</lang>
b = 8
fromBase = from b
toBase = to b</syntaxhighlight>
{{out}}
<pre>10000000 <-> 2097152
Line 695 ⟶ 1,234:
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main()
every i := 2097152 | 2097151 | 1 | 127 | 128 | 589723405834 | 165 | 256 do
write(image(i)," = ",string2hex(v := uint2vlq(i))," = ",vlq2uint(v))
Line 724 ⟶ 1,263:
h ||:= "0123456789abcdef"[i/16+1] || "0123456789abcdef"[i%16+1]
return h
end</langsyntaxhighlight>
 
Output:<pre>2097152 = 81808000 = 2097152
Line 737 ⟶ 1,276:
=={{header|J}}==
 
<langsyntaxhighlight lang="j">N=: 128x
v2i=: (N&| N&#./.~ [: +/\ _1 |. N&>)@i.~&a.
i2v=: a. {~ [:;}.@(N+//.@,:N&#.inv)&.>
ifv=: v2i :. i2v
vfi=: i2v :. v2i</lang>
av=: 3 u: ] </syntaxhighlight>
 
<code>ifv</code> is an invertible function which gets an (unsigned, arbitrary precision) integer sequence from a variable-length quantity sequence. <code>vfi</code> is an invertable function which gets a variable-length quantity sequence from an unsigned integer sequence. <code>av</code> displays character code numbers corresponding to the characters in its argument.
Line 747 ⟶ 1,287:
Example use:
 
<syntaxhighlight lang="j"> numbers=: 16b7f 16b4000 0 16b3ffffe 16b1fffff 200000
<lang j> require'convert'
numbers=: 16b7f 16b4000 0 16b3ffffe 16b1fffff 200000
av vlq=: vfi numbers
127 129 128 0 0 129 255 255 126 255 255 127 140 154 64
av (vfi 1 2 3 4 5 6) +&.ifv vlq
129 0 129 128 2 3 130 128 128 2 129 128 128 4 140 154 70</langsyntaxhighlight>
 
=={{header|Java}}==
 
<langsyntaxhighlight lang="java">public class VLQCode
{
public static byte[] encode(long n)
Line 815 ⟶ 1,354:
}
}
</syntaxhighlight>
</lang>
 
Output:
Line 824 ⟶ 1,363:
Original input=128, encoded = [81, 00], decoded=128, OK
Original input=589723405834, encoded = [91, 94, f2, 84, 9c, 0a], decoded=589723405834, OK</pre>
 
=={{header|JavaScript}}==
{{trans|Groovy}}
Based on programmatic experimentation, it breaks at 2147483648 (2^31).
 
<syntaxhighlight lang="javascript">const RADIX = 7;
const MASK = 2**RADIX - 1;
 
const octetify = (n)=> {
if (n >= 2147483648) {
throw new RangeError("Variable Length Quantity not supported for numbers >= 2147483648");
}
const octets = [];
for (let i = n; i != 0; i >>>= RADIX) {
octets.push((((i & MASK) + (octets.empty ? 0 : (MASK + 1)))));
}
octets.reverse();
return octets;
};
 
const deoctetify = (octets)=>
octets.reduce((n, octet)=>
(n << RADIX) + (octet & MASK)
, 0);
 
// Test (assuming Node.js)
 
const assert = require("assert");
const testNumbers = [ 0x200000, 0x1fffff, 1, 127, 128, 2147483647 /*, 589723405834*/ ]
 
testNumbers.forEach((number)=> {
const octets = octetify(number)
console.log(octets);
const got_back_number = deoctetify(octets)
assert.strictEqual(got_back_number, number);
});</syntaxhighlight>
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq and fq, the Go implementations'''
 
'''With minor tweaks, also works with jaq, the Rust implementation'''
 
<syntaxhighlight lang=jq>
# "VARIABLE-LENGTH QUANTITY"
# A VLQ is a variable-length encoding of a number into a sequence of octets,
# with the most-significant octet first, and with the most significant bit first in each octet.
# The first (left-most) bit in each octet is a continuation bit: all octets except the last have the left-most bit set.
# The bits of the original number are taken 7 at a time from the right to form the octets.
# Thus, if the number is between 0 and 127, it is represented exactly as one byte.
 
# Produce a stream of the base $b "digits" of the input number,
# least significant first, with a final 0
def digits($b):
def mod: . % $b;
def div: ((. - mod) / $b);
recurse( select(. > 0) | div) | mod ;
 
# 2 <= $b <= 36
def tobase($b):
def digit: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[.:.+1];
if . == 0 then "0"
else [digits($b) | digit] | reverse[1:] | add
end;
 
# input: a decimal integer
# output: the corresponding variable-length quantity expressed as an array of strings of length 2,
# each representing an octet in hexadecimal notation, with most-significant octet first.
def vlq:
def lpad: if length == 2 then . else "0" + . end;
[digits(128) + 128] | reverse[1:] | .[-1] -=128 | map(tobase(16) | lpad);
 
# Input: a VLQ as produced by vlq/0
# Output: the corresponding decimal
def vlq2dec:
def x2d: # convert the character interpreted as a hex digit to a decimal
explode[0] as $x
| if $x < 65 then $x - 48 elif $x < 97 then $x - 55 else $x - 87 end;
map( ((.[0:1] | x2d) * 16) + (.[1:] | x2d) - 128)
| .[-1] += 128 # the most significant bit of the least significant octet
| reduce reverse[] as $x ({x: 0, m: 1}; .x += ($x * .m) | .m *= 128)
| .x ;
 
# The task
 
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
 
2097152, 2097151
| vlq as $vlq
| "\(lpad(8)) => \($vlq|join(",")|lpad(12)) => \($vlq | vlq2dec | lpad(8))"
</syntaxhighlight>
{{output}}
<pre>
2097152 => 81,80,80,00 => 2097152
2097151 => FF,FF,7F => 2097151
</pre>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Printf
<lang Julia>
 
type VLQ
mutable struct VLQ
q::Array{Uint8,1}
quant::Vector{UInt8}
end
 
function VLQ{T<:Integer}(n::T) where T <: Integer
qquant = uint8UInt8.(digits(n, 128))
@inbounds for i in 2:length(qquant) quant[i] |= 0x80 end
VLQ(reverse(quant))
q[i] |= 0x80
end
VLQ(reverse(q))
end
 
functionimport Base.uint(vlq::VLQ)UInt64
function Base.UInt64(vlq::VLQ)
q = reverse(vlq.q)
nquant = shift!reverse(qvlq.quant)
pn = oneshift!(Uint64quant)
forp i= in qone(UInt64)
for i in quant
p *= 0x80
n += p * ( i & 0x7f)
end
return n
end
 
const test = [0x00200000, 0x001fffff, 0x00000000, 0x0000007f,
0x00000080, 0x00002000, 0x00003fff, 0x00004000,
0x08000000, 0x0fffffff]
 
for i in test
qvlq = VLQ(i)
j = uintUInt(qvlq)
@printf "0x%-8x => [%-25s] => 0x%x\n" i join(("0x" * hex(r, 2) for r in vlq.quant), ", ") j
print(@sprintf " 0x%x => " i)
end</syntaxhighlight>
print(@sprintf "[%s]" join(["0x"*hex(r, 2) for r in q.q], ", "))
println(@sprintf " => 0x%x" j)
end
</lang>
 
{{out}}
<pre>0x200000 => [0x81, 0x80, 0x80, 0x00 ] => 0x200000
<pre>
0x1fffff 0x200000 => [0x810xff, 0x800xff, 0x80,0x7f 0x00] => 0x2000000x1fffff
0x0 0x1fffff => [0xff,0x00 0xff, 0x7f] => 0x1fffff0x0
0x7f 0x0 => [0x000x7f ] => 0x00x7f
0x80 0x7f => [0x7f0x81, 0x00 ] => 0x7f0x80
0x2000 0x80 => [0x810xc0, 0x00 ] => 0x800x2000
0x3fff 0x2000 => [0xc00xff, 0x000x7f ] => 0x20000x3fff
0x4000 0x3fff => [0xff0x81, 0x7f0x80, 0x00 ] => 0x3fff0x4000
0x8000000 0x4000 => [0x810xc0, 0x80, 0x80, 0x00 ] => 0x40000x8000000
0xfffffff 0x8000000 => [0xc00xff, 0x800xff, 0x800xff, 0x000x7f ] => 0x80000000xfffffff</pre>
0xfffffff => [0xff, 0xff, 0xff, 0x7f] => 0xfffffff
</pre>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun Int.toOctets(): ByteArray {
Line 908 ⟶ 1,538:
println("${s.padEnd(20)} <- ${"0x%x".format(ba.fromOctets())}")
}
}</langsyntaxhighlight>
 
{{out}}
Line 918 ⟶ 1,548:
</pre>
 
=={{header|LiveCodexTalk}}==
{{works with|LiveCode}}
 
This task was completed a different (and better) way a long time ago in UDI's PMD/MakeSMF Lib for LiveCode (back when it was MetaCard).
Line 924 ⟶ 1,555:
-- Paul McClernan
 
<syntaxhighlight lang="livecode">
<lang LiveCode>
on DecToVLQ
Ask "Enter base 10 value:" -- input dialog box
Line 1,011 ⟶ 1,642:
return true
end isWholeNumString
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,022 ⟶ 1,653:
Convert back:
 
<syntaxhighlight lang="livecode">
<lang LiveCode>
function VLQtoWholeNum theHexVLQ
-- The number must be an integer between zero and 4,294,967,295
Line 1,090 ⟶ 1,721:
end if
end VLQHexToWholeNum
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,098 ⟶ 1,729:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">toOctets[n_Integer] :=
StringJoin @@@
Partition[
PadLeft[Characters@IntegerString[n, 16],
2 Ceiling[Plus @@ DigitCount[n, 16]/2], {"0"}], 2]
 
fromOctets[octets_List] := FromDigits[StringJoin @@ octets, 16]
Grid[{#, toOctets@#, fromOctets[toOctets@#]} & /@ {16^^3ffffe, 16^^1fffff, 16^^200000}]</syntaxhighlight>
{{out}}
Grid[{#, toOctets@#, fromOctets[toOctets@#]} & /@ {16^^3ffffe,
<pre>4194302 {3f,ff,fe} 4194302
16^^1fffff, 16^^200000}]</lang>
{{out}}<pre>
4194302 {3f,ff,fe} 4194302
2097151 {1f,ff,ff} 2097151
2097152 {20,00,00} 2097152</pre>
</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang ="nim">import unsigned, strutilsstrformat
 
proc toSeq(x: uint64): seq[uint8] =
var x = x
resultvar f = @[]0u64
for i in countdown(9u64, 1):
var f = 0
if (x and 127'u64 shl (i * 7)) > 0:
for i in countdown(9, 1):
if (x and (127'u64 shl uint((i * 7)))) > 0'u64:
f = i
break
for j in 00u64..f:
result.add( uint8((x shr uint64((f - j) * 7)) and 127) or 128)
 
result[f] = result[f] xor 128'u8
 
proc fromSeq(xs: openArray[uint8]): uint64 =
result = 0
for x in xs:
result = (result shl 7) or (x and 127)
Line 1,139 ⟶ 1,764:
0x200000'u64, 0x3311a1234df31413'u64]:
let c = toSeq(x)
echo &"seq from $#{x}: $#{c} back: $#".format(x, c, {fromSeq(c))}"</langsyntaxhighlight>
 
Output:
{{out}}
<pre>seq from 127: @[127] back: 127
seq from 16384: @[129, 128, 0] back: 16384
Line 1,150 ⟶ 1,776:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let to_vlq n =
let a, b = n lsr 7, n land 0x7F in
let rec aux n acc =
Line 1,174 ⟶ 1,800:
v_rep 0x200000;
v_rep 0x1FFFFF
</syntaxhighlight>
</lang>
 
Outputs:
Line 1,183 ⟶ 1,809:
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">hex(s)=my(a=10,b=11,c=12,d=13,e=14,f=15);subst(Pol(eval(Vec(s))),'x,16);
n1=hex("200000");n2=hex("1fffff");
v1=digits(n1,256)
v2=digits(n2,256)
subst(Pol(v1),'x,256)==n1
subst(Pol(v2),'x,256)==n2</langsyntaxhighlight>
{{out}}
<pre>%1 = [32, 0, 0]
Line 1,198 ⟶ 1,824:
The vlg_encode sub returns an array of octets in most -> least significant order. Simply reverse the array to reverse the order.
 
<langsyntaxhighlight lang="perl">
use warnings;
use strict;
Line 1,229 ⟶ 1,855:
return oct '0b' . $num;
}
</syntaxhighlight>
</lang>
 
Output:
Line 1,246 ⟶ 1,872:
65537 84:80:01 65537
2097151 ff:ff:7f 2097151
2097152 81:80:80:00 2097152
</pre>
 
=={{header|Perl 6}}==
vlq_encode() returns a string of characters whose ordinals are the encoded octets. vlq_decode() takes a string and returns a decimal number.
<lang perl6>sub vlq_encode ($number is copy) {
my $string = '';
my $t = 0x7F +& $number;
$number +>= 7;
$string = $t.chr ~ $string;
while ($number) {
$t = 0x7F +& $number;
$string = (0x80 +| $t).chr ~ $string;
$number +>= 7;
}
return $string;
}
 
sub vlq_decode ($string is copy) {
my $number = '0b';
for $string.ords -> $oct {
$number ~= ($oct +& 0x7F).fmt("%07b");
}
return :2($number);
}
 
#test encoding and decoding
for (
0, 0xa, 123, 254, 255, 256,
257, 65534, 65535, 65536, 65537, 0x1fffff,
0x200000
) -> $testcase {
my $encoded = vlq_encode($testcase);
printf "%8s %12s %8s\n", $testcase,
( join ':', $encoded.ords>>.fmt("%02X") ),
vlq_decode($encoded);
}</lang>
 
Output:
<pre>
0 00 0
10 0A 10
123 7B 123
254 81:7E 254
255 81:7F 255
256 82:00 256
257 82:01 257
65534 83:FF:7E 65534
65535 83:FF:7F 65535
65536 84:80:00 65536
65537 84:80:01 65537
2097151 FF:FF:7F 2097151
2097152 81:80:80:00 2097152
</pre>
Line 1,303 ⟶ 1,877:
=={{header|Phix}}==
Copy of [[Variable-length_quantity#Euphoria|Euphoria]], modified to pack several numbers into a single stream. Also added an explicit check that (as per wp) only unsigned numbers are attempted.
 
<lang Phix>function vlq_encode(sequence s)
<!--<syntaxhighlight lang="phix">-->
sequence res = {}
<span style="color: #008080;">function</span> <span style="color: #000000;">vlq_encode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
integer n, msb
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for i=length(s) to 1 by -1 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
n = s[i]
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">msb</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
if n<0 then crash("unsigned integers only!") end if
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"unsigned integers only!"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
msb = 0
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
while 1 do
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">prepend</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">msb</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#7F</span><span style="color: #0000FF;">))</span>
res = prepend(res,msb+and_bits(n,#7F))
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">#80</span><span style="color: #0000FF;">)</span>
n = floor(n/#80)
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if n=0 then exit end if
<span style="color: #000000;">msb</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#80</span>
msb = #80
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">vlq_decode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
function vlq_decode(sequence s)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
sequence res = {}
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
integer n = 0, byte
<span style="color: #004080;">integer</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
for i=1 to length(s) do
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">#80</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #004080;">byte</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#7F</span><span style="color: #0000FF;">)</span>
byte = s[i]
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#80</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
n = n*#80+and_bits(byte,#7F)
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
if not and_bits(byte,#80) then
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
res = append(res,n)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
n = 0
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return res
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">svlg</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
function svlg(sequence s)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
string res = ""
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"#%02x:"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]})</span>
for i=1 to length(s) do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
res &= sprintf("#%02x:",{s[i]})
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return res[1..$-1]
end function
<span style="color: #008080;">constant</span> <span style="color: #000000;">testNumbers</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> <span style="color: #000000;">#200000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#1FFFFF</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">127</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">128</span> <span style="color: #0000FF;">}</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">vlq_encode</span><span style="color: #0000FF;">(</span><span style="color: #000000;">testNumbers</span><span style="color: #0000FF;">),</span>
constant testNumbers = { #200000, #1FFFFF, 1, 127, 128 }
<span style="color: #000000;">decoded</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">vlq_decode</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
sequence s = vlq_encode(testNumbers)
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s -> %s -> %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">svlg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">testNumbers</span><span style="color: #0000FF;">),</span><span style="color: #000000;">svlg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span><span style="color: #000000;">svlg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">decoded</span><span style="color: #0000FF;">)})</span>
sequence decoded = vlq_decode(s)
<span style="color: #008080;">if</span> <span style="color: #000000;">decoded</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">testNumbers</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"something wrong"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
printf(1,"%s -> %s -> %s\n",{svlg(testNumbers),svlg(s),svlg(decoded)})
<!--</syntaxhighlight>-->
if decoded!=testNumbers then crash("something wrong") end if</lang>
 
{{out}}
<pre>
Line 1,353 ⟶ 1,928:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de numToVlq (Num)
(let Res (cons (& Num 127))
(while (gt0 (setq Num (>> 7 Num)))
Line 1,366 ⟶ 1,941:
(for Num (0 15 16 127 128 255 2097151 2097152)
(let Vlq (numToVlq Num)
(tab (12 12 12) Num (glue ":" (mapcar hex Vlq)) (vlqToNum Vlq)) ) )</langsyntaxhighlight>
Output:
<pre> 0 0 0
Line 1,378 ⟶ 1,953:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
test: procedure options(main);
declare s character (20) varying;
Line 1,407 ⟶ 1,982:
put skip list (hs);
end test;
</syntaxhighlight>
</lang>
OUTPUT:
<pre>
Line 1,421 ⟶ 1,996:
When transmitting the Vlq, octets are sent from the rightmost of the Vlq first.
 
<langsyntaxhighlight lang="python">def tobits(n, _group=8, _sep='_', _pad=False):
'Express n as binary bits with separator'
bits = '{0:b}'.format(n)[::-1]
Line 1,443 ⟶ 2,018:
def vlqsend(vlq):
for i, byte in enumerate(vlq.split('_')[::-1]):
print('Sent byte {0:3}: {1:#04x}'.format(i, int(byte,2)))</langsyntaxhighlight>
 
<br>'''Sample Output'''
The underscore separates groups of eight bits (octets), for readability
<langsyntaxhighlight lang="python">>>> for n in (254, 255, 256, 257, -2+(1<<16), -1+(1<<16), 1<<16, 1+(1<<16), 0x200000, 0x1fffff ):
print('int: %7i bin: %26s vlq: %35s vlq->int: %7i' % (n, tobits(n,_pad=True), tovlq(n), toint(tovlq(n))))
 
Line 1,470 ⟶ 2,045:
Sent byte 1: 0xff
Sent byte 2: 0x7f
>>> </langsyntaxhighlight>
 
 
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
 
Line 1,491 ⟶ 2,065:
 
(for-each try '(#x200000 #x1fffff))
</syntaxhighlight>
</lang>
 
Output:
Line 1,501 ⟶ 2,075:
Octets: ff:ff:1f:0 (byte-string: #"\377\377\37\0")
Back to a number: 2097151 (OK)
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
vlq_encode() returns a string of encoded octets. vlq_decode() takes a string and returns a decimal number.
<syntaxhighlight lang="raku" line>sub vlq_encode ($number is copy) {
my @vlq = (127 +& $number).fmt("%02X");
$number +>= 7;
while ($number) {
@vlq.push: (128 +| (127 +& $number)).fmt("%02X");
$number +>= 7;
}
@vlq.reverse.join: ':';
}
 
sub vlq_decode ($string) {
sum $string.split(':').reverse.map: {(:16($_) +& 127) +< (7 × $++)}
}
 
#test encoding and decoding
for (
0, 0xa, 123, 254, 255, 256,
257, 65534, 65535, 65536, 65537, 0x1fffff,
0x200000
) -> $testcase {
printf "%8s %12s %8s\n", $testcase,
my $encoded = vlq_encode($testcase),
vlq_decode($encoded);
}</syntaxhighlight>
 
Output:
<pre>
0 00 0
10 0A 10
123 7B 123
254 81:7E 254
255 81:7F 255
256 82:00 256
257 82:01 257
65534 83:FF:7E 65534
65535 83:FF:7F 65535
65536 84:80:00 65536
65537 84:80:01 65537
2097151 FF:FF:7F 2097151
2097152 81:80:80:00 2097152
</pre>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program todisplays display (and also testtests/verifyverifies) some numbers as octets. */
nums = x2d(200000) x2d(1fffff) 2097172 2097151
#=words(nums)
say ' number hex octet original'
say '══════════ ══════════ ══════════ ══════════'
say '═════════ ═════════ ═════════ ═════════'
ok=1
do j=1 for #; @.j= word(nums,j)
onum.j=octet(@.j)
orig.j= x2d( space(onum.j, 0) )
w=10
 
say showcenter(@.j, w) show center(d2x(@.j), w) show center(onum.j, w) show center(orig.j, w)
if @.j\==orig.j then ok=0
end /*j*/
say
if ok then say 'All ' # " numbers are OK." /*all of the numbers /*allare numbers good. */
else say 'Trouble"Some rightnumbers hereare innot River CityOK.'" /*some numberof the numbers are ¬good. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────OCTET subroutine────────────────────*/
octet: procedure; parse arg az,_$ /*obtain AZ from the passed argarguments. */
x=d2x(az) /*convert AZ to a hexadecimal octet. */
do j=length(x) by -2 to 1 /*process the "little" end first. */
_ $= substr(x, j-1, 2, 0) _ $ /*pad odd hexcharactershexadecimal characters with ··· */
end /*j*/ /* ··· a zero on the left. */
return strip($)</syntaxhighlight>
return _
{{out|output|text=&nbsp; when using the default input:}}
/*──────────────────────────────────SHOW subroutine─────────────────────*/
show: return center(arg(1),9) /*justify via centering the text.*/</lang>
'''output'''
<pre>
number hex octet original
══════════ ══════════ ══════════ ══════════
═════════ ═════════ ═════════ ═════════
2097152 200000 20 00 00 2097152
2097151 1FFFFF 1F FF FF 2097151
2097172 200014 20 00 14 2097172
2097151 1FFFFF 1F FF FF 2097151
 
All 4 numbers are OK.
</pre>
 
=={{header|RPL}}==
{{works with|Halcyon Calc|4.2.8}}
{| class="wikitable"
! RPL code
! Comment
|-
|
R→B { } SWAP 1 SF
'''WHILE''' DUP #0 ≠ '''REPEAT'''
DUP #7Fh AND
'''IF''' 1 FC?C '''THEN''' #80h OR '''END''''
ROT + SWAP
1 7 '''START''' SR '''NEXT '''
'''END''' DROP
≫ ''''R→VLQ'''' STO
#0 SWAP 1 OVER SIZE '''FOR''' j
DUP j GET #7Fh AND
ROT SLB SR + SWAP
'''NEXT''' DROP B→R
≫ ''''VLQ→R'''' STO
|
'''R→VLQ''' ''( n -- { #VLQ } )''
initialize stack and flag
scan the input number
keep last 7 bits
set sign bit if not the first set of 7 bits
store in list
shift 7 bits right
clean stack
'''R→VLQ''' ''( { #VLQ } -- n )''
initialize stack and VLQ scan
get a byte, remove 1st bit
multiply previous sum by 128 then add byte
clean stack, convert to floating point
|}
{{in}}
<pre>
2097152 R→VLQ
2097151 R→VLQ
106903 R→VLQ
DUP VLQ→R
</pre>
{{out}}
<pre>
4: { #81h #80h #80h #0h }
3: { #FFh #FFh #7Fh }
2: { #86h #C3h #17h }
1: 106903
</pre>
 
Line 1,545 ⟶ 2,218:
Array#pack can encode the ''BER-compressed integer'', which is identical to the ''variable-length quantity'' from the [http://sander.vanzoest.com/talks/2002/audio_and_apache/midispec.html MIDI specification]. String#unpack can decode it.
 
<langsyntaxhighlight lang="ruby">[0x200000, 0x1fffff].each do |i|
# Encode i => BER
ber = [i].pack("w")
Line 1,554 ⟶ 2,227:
j = ber.unpack("w").first
i == j or fail "BER not preserve integer"
end</langsyntaxhighlight>
 
<pre>2097152 => 81:80:80:00
Line 1,560 ⟶ 2,233:
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">object VlqCode {
def encode(x:Long)={
val result=scala.collection.mutable.Stack[Byte]()
Line 1,586 ⟶ 2,259:
xs foreach test
}
}</langsyntaxhighlight>
Output:
<pre>0x0 => [00] => 0x0
Line 1,605 ⟶ 2,278:
The example below uses [http://seed7.sourceforge.net/libraries/bigint.htm bigInteger] numbers,
since variable-length quantities are able to represent integer numbers of unlimited size.
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "bigint.s7i";
Line 1,651 ⟶ 2,324:
writeln("] back: " <& fromSequence(sequence));
end for;
end func;</langsyntaxhighlight>
 
Output:
Line 1,671 ⟶ 2,344:
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">func vlq_encode(num) {
var t = (0x7F & num)
var str = t.chr
Line 1,698 ⟶ 2,371:
printf("%8s %12s %8s\n", t,
vlq.bytes.join(':', { "%02X" % _ }), vlq_decode(vlq))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,717 ⟶ 2,390:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
proc vlqEncode number {
Line 1,739 ⟶ 2,412:
}
return $n
}</langsyntaxhighlight>
Demo code:
<langsyntaxhighlight lang="tcl">proc numtohex {num} {
binary scan [string trimleft [binary format W $num] \0] H* hexEncoded
regsub -all "..(?=.)" $hexEncoded "&:"
Line 1,763 ⟶ 2,436:
[strtohex $encoded] ([string length $encoded] bytes) ==>\
$decoded"
}</langsyntaxhighlight>
Output:
<pre>
Line 1,782 ⟶ 2,455:
=={{header|TXR}}==
 
TXR's <code>carray</code> type, closely associated with the Foreign Function Interface, has functions for converting between integers and foreign arrays. The arrays can use any element type. The integer is stored in big endian order, and "right justified" within the buffer, so that its least significant byte is aligned with the least significant byte of the last element of the array.
In TXR, the preferred way to render data into octets is to convert it to a character string. Character strings are Unicode, which serializes to UTF-8 when sent to text streams.
 
Two representations are supported: unsigned and signed. The unsigned representation takes only non-negative integers. It is a straightforward pure binary enumeration. The signed representation uses twos complement. The most significant byte of the array representation is in the range 80-FF if the value is negative, otherwise in the range 0 to 7F. This means that in some cases, a zero byte has to be added.
<lang txrlisp>;; show the utf8 bytes from byte stream as hex
(defun put-utf8 (str : stream)
(set stream (or stream *stdout*))
(for ((s (make-string-byte-input-stream str)) byte)
((set byte (get-byte s)))
((format stream "\\x~,02x" byte))))
 
Interactive session:
;; print
(put-utf8 (tostring 0))
(put-line "")
(put-utf8 (tostring 42))
(put-line "")
(put-utf8 (tostring #x200000))
(put-line "")
(put-utf8 (tostring #x1fffff))
(put-line "")
 
<pre>1> (carray-num #x200000)
;; print to string and recover
#<carray 3 #<ffi-type uchar>>
(format t "~a\n" (read (tostring #x200000)))
2> (carray-get *1)
(format t "~a\n" (read (tostring #x1f0000)))</lang>
#(32 0 0)
3> (carray-num #x1FFFFF)
#<carray 3 #<ffi-type uchar>>
4> (carray-get *3)
#(31 255 255)
5> (num-carray *1)
2097152
6> (num-carray *3)
2097151</pre>
 
Conversion to a <code>carray</code> not based on the default <code>uchar</code>:
Run:
 
<pre>1> (carray-num #x123456789 (ffi uint32))
<pre>\x30
#<carray 2 #<ffi-type uint32>>
\x34\x32
2> (carray-get *1)
\x32\x30\x39\x37\x31\x35\x32
#(16777216 2305246499)</pre>
\x32\x30\x39\x37\x31\x35\x31
 
2097152
This number requires two 32-bit units to store. Because <code>uint32</code> is in the native endian, opposite to the big endian storage of the integer, the words come out byte swapped. The <code>be-uint32</code> type could be used to change this.
2031616</pre>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
{{libheader|Wren-str}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt, Conv
import "./str" for Str
 
var toOctets = Fn.new { |n|
var s = Conv.itoa(n, 2)
var le = s.count
var r = le % 7
var d = (le/7).floor
if (r > 0) {
d = d + 1
s = Fmt.zfill(7 * d, s)
}
var chunks = Str.chunks(s, 7)
var last = "0" + chunks[-1]
s = chunks[0..-2].map { |ch| "1" + ch }.join() + last
return Str.chunks(s, 8).map { |ch| Conv.atoi(ch, 2) }.toList
}
 
var fromOctets = Fn.new { |octets|
var s = ""
for (oct in octets) {
var bin = Conv.itoa(oct, 2)
bin = Fmt.zfill(7, bin)
s = s + bin[-7..-1]
}
return Conv.atoi(s, 2)
}
 
var tests = [2097152, 2097151]
for (test in tests) {
var octets = toOctets.call(test)
var display = octets.map { |oct| "Ox" + Fmt.xz(2, oct) }.toList
System.write("%(test) -> %(Fmt.v("s", 4, display, 0, " ", "")) -> ")
System.print(fromOctets.call(octets))
}</syntaxhighlight>
 
{{out}}
<pre>
2097152 -> Ox81 Ox80 Ox80 Ox00 -> 2097152
2097151 -> Oxff Oxff Ox7f -> 2097151
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">func OctIn(Dev); \Input from device value of sequence of octets
int Dev, N, Oct;
[N:= 0;
repeat Oct:= HexIn(Dev);
N:= N<<7 + (Oct&$7F);
until (Oct&$80) = 0;
return N;
];
 
proc OctOut(Dev, Num, Lev); \Output value to device as sequence of octets
int Dev, Num, Lev, Rem;
[Rem:= Num & $7F;
Num:= Num >> 7;
if Num # 0 then OctOut(Dev, Num, Lev+1);
if Lev > 0 then Rem:= Rem + $80;
SetHexDigits(2);
HexOut(Dev, Rem);
ChOut(Dev, ^ );
];
 
\Device 8 is a circular buffer that can be written and read back.
int N;
[for N:= 0 to $40_0000 do
[OctOut(8, N, 0);
if N # OctIn(8) then
[Text(0, "Error!"); exit];
];
OctOut(0, $1F_FFFF, 0); CrLf(0);
OctOut(0, $20_0000, 0); CrLf(0);
OctOut(0, $7F, 0); CrLf(0);
OctOut(0, $4000, 0); CrLf(0);
OctOut(0, 0, 0); CrLf(0);
OctOut(0, $3F_FFFE, 0); CrLf(0);
OctOut(0, $FFFF_FFFF, 0); CrLf(0);
]</syntaxhighlight>
 
{{out}}
<pre>
FF FF 7F
81 80 80 00
7F
81 80 00
00
81 FF FF 7E
8F FF FF FF 7F
</pre>
 
=={{header|zkl}}==
{{trans|C}}
<langsyntaxhighlight lang="zkl">fcn to_seq(x){ //--> list of ints
z:=(x.log2()/7);
(0).pump(z+1,List,'wrap(j){
Line 1,823 ⟶ 2,585:
}
 
fcn from_seq(in){ in.reduce(fcn(p,n){ p.shiftLeft(7).bitOr(n.bitAnd(0x7f)) },0) }</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">ns:=T(0x7f, 0x4000, 0, 0x3ffffe, 0x1fffff, 0x200000, 0x3311a1234df31413);
ms:=ns.apply(to_seq);
ns.zipWith(fcn{"%8,x --> %s --> %,x".fmt(vm.arglist.xplode()).println()},
ms.apply("apply","%,x".fmt),
ms.apply(from_seq));</langsyntaxhighlight>
{{out}}
<pre>
2,122

edits