Variable-length quantity: Difference between revisions

Added FreeBASIC
(Added 11l)
(Added FreeBASIC)
 
(16 intermediate revisions by 12 users not shown)
Line 14:
{{trans|C++}}
 
<langsyntaxhighlight lang="11l">F to_str(v)
R ‘[ ’v.map(n -> hex(n).lowercase().zfill(2)).join(‘ ’)‘ ]’
 
Line 39:
R r
 
L(x) [UInt64(7'fF), 40'00, 0, 003f003F'fffeFFFE, 001f001F'ffffFFFF, 0020'0000, 3311'a123A123'4df34DF3'1413]
V s = to_seq(x)
print(‘seq from ’hex(x).lowercase()‘ ’to_str(s)‘ back: ’hex(from_seq(s)).lowercase())</langsyntaxhighlight>
 
{{out}}
Line 56:
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Containers.Vectors;
with Ada.Text_IO;
with Ada.Unchecked_Conversion;
Line 147:
Nat_IO.Put (To_Int (Test), 10, 16); Ada.Text_IO.Put (" = ");
Print (Test);
end VLQ;</langsyntaxhighlight>
 
Output:
Line 157:
16#200000# = :16#81#:16#80#:16#80#: 16#0#</pre>
 
=={{header|ANSI Standard BASIC}}==
<lang ==={{header|ANSI BASIC>INPUT s$}}===
{{works with|Decimal BASIC}}
<syntaxhighlight lang="basic">INPUT s$
LET s$ = LTRIM$(RTRIM$(s$))
LET v = 0
Line 179 ⟶ 181:
NEXT i
PRINT hs$
END</langsyntaxhighlight>
{{out}}
OUTPUT:
<pre>
S= 200000 V= 2097152
Line 187 ⟶ 189:
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 245 ⟶ 420:
& test$82
& test$894E410E0A
);</langsyntaxhighlight>
Output:
<pre>input: 200000
Line 281 ⟶ 456:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdint.h>
 
Line 323 ⟶ 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 329 ⟶ 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}}
<langsyntaxhighlight lang="cpp">#include <iomanip>
#include <iostream>
#include <vector>
Line 390 ⟶ 565:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>seq from 7f [ 7f ] back: 7f
Line 402 ⟶ 577:
=={{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 505 ⟶ 680:
}
}
}</langsyntaxhighlight>output<syntaxhighlight lang="text">Original: 0xFE000000000000
Sequence: 0xFF80808080808000
Decoded: 0xFE000000000000
Line 547 ⟶ 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 635 ⟶ 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 649 ⟶ 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 664 ⟶ 1,051:
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">function vlq_encode(integer n)
sequence s
s = {}
Line 704 ⟶ 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 716 ⟶ 1,103:
=={{header|Go}}==
Go has an implementation of variable length quantities in the standard library.
<langsyntaxhighlight lang="go">package main
 
import (
Line 731 ⟶ 1,118:
fmt.Println(x, "decoded")
}
}</langsyntaxhighlight>
Output required by task:
<pre>
Line 763 ⟶ 1,150:
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">final RADIX = 7
final MASK = 2**RADIX - 1
Line 778 ⟶ 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 788 ⟶ 1,175:
def a1 = deoctetify(octets)
assert a1 == a
}</langsyntaxhighlight>
 
Output:
Line 800 ⟶ 1,187:
=={{header|Haskell}}==
 
<langsyntaxhighlight Haskelllang="haskell">import Numeric (readOct, showOct)
import Data.List (intercalate)
 
Line 814 ⟶ 1,201:
(putStrLn .
intercalate " <-> " . (pure (:) <*> to <*> (return . show . from . to)))
[2097152, 2097151]</langsyntaxhighlight>
 
Homemade Version:
 
<langsyntaxhighlight Haskelllang="haskell">import Data.List (intercalate)
 
to :: Int -> Int -> [Int]
Line 841 ⟶ 1,228:
b = 8
fromBase = from b
toBase = to b</langsyntaxhighlight>
{{out}}
<pre>10000000 <-> 2097152
Line 847 ⟶ 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 876 ⟶ 1,263:
h ||:= "0123456789abcdef"[i/16+1] || "0123456789abcdef"[i%16+1]
return h
end</langsyntaxhighlight>
 
Output:<pre>2097152 = 81808000 = 2097152
Line 889 ⟶ 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 899 ⟶ 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 967 ⟶ 1,354:
}
}
</syntaxhighlight>
</lang>
 
Output:
Line 981 ⟶ 1,368:
Based on programmatic experimentation, it breaks at 2147483648 (2^31).
 
<langsyntaxhighlight lang="javascript">const RADIX = 7;
const MASK = 2**RADIX - 1;
 
Line 1,011 ⟶ 1,398:
const got_back_number = deoctetify(octets)
assert.strictEqual(got_back_number, number);
});</langsyntaxhighlight>
 
=={{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}}==
<langsyntaxhighlight lang="julia">using Printf
 
mutable struct VLQ
Line 1,046 ⟶ 1,493:
j = UInt(vlq)
@printf "0x%-8x => [%-25s] => 0x%x\n" i join(("0x" * hex(r, 2) for r in vlq.quant), ", ") j
end</langsyntaxhighlight>
 
{{out}}
Line 1,061 ⟶ 1,508:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun Int.toOctets(): ByteArray {
Line 1,091 ⟶ 1,538:
println("${s.padEnd(20)} <- ${"0x%x".format(ba.fromOctets())}")
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,101 ⟶ 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 1,107 ⟶ 1,555:
-- Paul McClernan
 
<syntaxhighlight lang="livecode">
<lang LiveCode>
on DecToVLQ
Ask "Enter base 10 value:" -- input dialog box
Line 1,194 ⟶ 1,642:
return true
end isWholeNumString
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,205 ⟶ 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,273 ⟶ 1,721:
end if
end VLQHexToWholeNum
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,281 ⟶ 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}}==
<langsyntaxhighlight lang="nim">import strformat
 
proc toSeq(x: uint64): seq[uint8] =
Line 1,320 ⟶ 1,764:
0x200000'u64, 0x3311a1234df31413'u64]:
let c = toSeq(x)
echo &"seq from {x}: {c} back: {fromSeq(c)}"</langsyntaxhighlight>
 
{{out}}
Line 1,332 ⟶ 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,356 ⟶ 1,800:
v_rep 0x200000;
v_rep 0x1FFFFF
</syntaxhighlight>
</lang>
 
Outputs:
Line 1,365 ⟶ 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,380 ⟶ 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,411 ⟶ 1,855:
return oct '0b' . $num;
}
</syntaxhighlight>
</lang>
 
Output:
Line 1,434 ⟶ 1,878:
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.
 
<!--<langsyntaxhighlight Phixlang="phix">-->
<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>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
Line 1,476 ⟶ 1,920:
<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>
<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>
<!--</langsyntaxhighlight>-->
 
{{out}}
Line 1,484 ⟶ 1,928:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de numToVlq (Num)
(let Res (cons (& Num 127))
(while (gt0 (setq Num (>> 7 Num)))
Line 1,497 ⟶ 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,509 ⟶ 1,953:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
test: procedure options(main);
declare s character (20) varying;
Line 1,538 ⟶ 1,982:
put skip list (hs);
end test;
</syntaxhighlight>
</lang>
OUTPUT:
<pre>
Line 1,552 ⟶ 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,574 ⟶ 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,601 ⟶ 2,045:
Sent byte 1: 0xff
Sent byte 2: 0x7f
>>> </langsyntaxhighlight>
 
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
 
Line 1,621 ⟶ 2,065:
 
(for-each try '(#x200000 #x1fffff))
</syntaxhighlight>
</lang>
 
Output:
Line 1,635 ⟶ 2,079:
=={{header|Raku}}==
(formerly 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.
<syntaxhighlight lang="raku" perl6line>sub vlq_encode ($number is copy) {
my $string@vlq = ''(127 +& $number).fmt("%02X");
my $t = 0x7F +& $number;
$number +>= 7;
$string = $t.chr ~ $string;
while ($number) {
$t@vlq.push: =(128 +| 0x7F(127 +& $number)).fmt("%02X");
$string = (0x80 +| $t).chr ~ $string;
$number +>= 7;
}
@vlq.reverse.join: ':';
return $string;
}
 
sub vlq_decode ($string is copy) {
sum $string.split(':').reverse.map: {(:16($_) +& 127) +< (7 × $++)}
my $number = '0b';
for $string.ords -> $oct {
$number ~= ($oct +& 0x7F).fmt("%07b");
}
return :2($number);
}
 
Line 1,663 ⟶ 2,100:
0x200000
) -> $testcase {
my $encoded = vlq_encode($testcase);
printf "%8s %12s %8s\n", $testcase,
my $encoded = vlq_encode($testcase),
( join ':', $encoded.ords>>.fmt("%02X") ),
vlq_decode($encoded);
}</langsyntaxhighlight>
 
Output:
Line 1,687 ⟶ 2,123:
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program displays (and also tests/verifies) some numbers as octets. */
nums = x2d(200000) x2d(1fffff) 2097172 2097151
#=words(nums)
Line 1,710 ⟶ 2,146:
$= substr(x, j-1, 2, 0) $ /*pad odd hexadecimal characters with */
end /*j*/ /* ··· a zero on the left. */
return strip($)</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
Line 1,721 ⟶ 2,157:
 
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,726 ⟶ 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,735 ⟶ 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,741 ⟶ 2,233:
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">object VlqCode {
def encode(x:Long)={
val result=scala.collection.mutable.Stack[Byte]()
Line 1,767 ⟶ 2,259:
xs foreach test
}
}</langsyntaxhighlight>
Output:
<pre>0x0 => [00] => 0x0
Line 1,786 ⟶ 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,832 ⟶ 2,324:
writeln("] back: " <& fromSequence(sequence));
end for;
end func;</langsyntaxhighlight>
 
Output:
Line 1,853 ⟶ 2,345:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">func vlq_encode(num) {
var t = (0x7F & num)
var str = t.chr
Line 1,879 ⟶ 2,371:
printf("%8s %12s %8s\n", t,
vlq.bytes.join(':', { "%02X" % _ }), vlq_decode(vlq))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,898 ⟶ 2,390:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
proc vlqEncode number {
Line 1,920 ⟶ 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,944 ⟶ 2,436:
[strtohex $encoded] ([string length $encoded] bytes) ==>\
$decoded"
}</langsyntaxhighlight>
Output:
<pre>
Line 1,990 ⟶ 2,482:
 
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.
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<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</lang>
{{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|Wren}}==
{{libheader|Wren-fmt}}
{{libheader|Wren-str}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt, Conv
import "./str" for Str
 
var toOctets = Fn.new { |n|
Line 2,158 ⟶ 2,520:
System.write("%(test) -> %(Fmt.v("s", 4, display, 0, " ", "")) -> ")
System.print(fromOctets.call(octets))
}</langsyntaxhighlight>
 
{{out}}
Line 2,164 ⟶ 2,526:
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 2,175 ⟶ 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