<p>No. The compact size unsigned integers are not uints (except for the base one of one byte). They are a serialization, so it is actually just an array of bytes. You just compare the number you are serializing to the boundaries and determine from there what the prefix byte is. Bitcoin.org does a better job of describing this: <a href="https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers" rel="nofollow noreferrer">https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers</a>. Note that you will need to understand hex numbers are and how they work in C.</p>

CC BY-SA 3.0
2017-08-28T02:36:24.570Z
I implement a version of this method based on your sugestion, could you check if it's works? Also, there is some compiler warnings; do you have any sugestion of how to solve them?
Kleber Mota
CC BY-SA 3.0
2017-08-28T03:23:44.823Z
You are casting pointers to uints. Don't do that since you are changing the pointer type, not the number type. Instead you should cast the variable first, then get a pointer to it or cast to a type pointer (e.g. uint32_t*)
Ava Chow
CC BY-SA 3.0
2017-08-28T01:18:37.090Z
2017-08-28T01:18:37.090Z
Ava Chow
<p>Here is <a href="https://github.com/bitcoin/libblkmaker/blob/master/blkmaker.c#L93" rel="nofollow noreferrer"><code>libblkmaker</code></a>'s implementation:</p>

<pre><code>static
char varintEncode(unsigned char *out, uint64_t n) {
    if (n &lt; 0xfd)
    {
        out[0] = n;
        return 1;
    }
    char L;
    if (n &lt;= 0xffff)
    {
        out[0] = '\xfd';
        L = 3;
    }
    else
    if (n &lt;= 0xffffffff)
    {
        out[0] = '\xfe';
        L = 5;
    }
    else
    {
        out[0] = '\xff';
        L = 9;
    }
    for (unsigned char i = 1; i &lt; L; ++i)
        out[i] = (n &gt;&gt; ((i - 1) * 8)) % 256;
    return L;
}
</code></pre>

CC BY-SA 4.0
2018-11-06T21:02:53.523Z
2018-11-06T21:02:53.523Z
Geremia
<p>Anyone can give me a idea of how implement in C this concept of Variable length integer which encoded the numer of transactions in a block? based on what is described <a href="https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer" rel="nofollow noreferrer">here</a>, I think is something lime that:</p>

<pre><code>if(value=?)
    uint8_t number_transactions = length;
else if(value=?)
    uint16_t number_transactions = 0xFD+length;
else if(value=?)
    uint32_t number_transactions = 0xFE_length;
else
    uint64_t number_transactions = 0xFF_length;
</code></pre>

<p>where <code>number_transactions</code> would be the value concatenated on the block. But how implement this? This <a href="https://github.com/lemire/MaskedVByte/blob/master/src/varintencode.c" rel="nofollow noreferrer">code</a> does the same described in the bitcoin wiki?</p>

<p><strong>UPDATE</strong></p>

<pre><code>char* varint(unsigned long size) {
  char* number;
  if(size &lt; 252) {
    number = malloc(1);
    number[0] = (uint8_t)size;
  } else if(size&gt;=253 &amp;&amp; size&lt;65535) {
    number = malloc(3);
    number[0] = 0xfd;
    memcpy(&amp;number[1], (uint16_t)&amp;size, sizeof(uint16_t));
  } else if(size&gt;=65536 &amp;&amp; size&lt;4294967295) {
    number = malloc(5);
    number[0] = 0xfe;
    memcpy(&amp;number[1], (uint32_t)&amp;size, sizeof(uint32_t));
  } else if(size&gt;=4294967296) {
    number = malloc(9);
    number[0] = 0xff;
    memcpy(&amp;number[1], (uint64_t)&amp;size, sizeof(uint64_t));
  }
  return NULL;
}
</code></pre>

<p>message from compiler:</p>

<pre><code>bitcoin_rpc.c: In function ‘varint’:
bitcoin_rpc.c:230:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     memcpy(&amp;number[1], (uint16_t)&amp;size, sizeof(uint16_t));
                        ^
bitcoin_rpc.c:230:24: warning: passing argument 2 of ‘memcpy’ makes pointer from integer without a cast [-Wint-conversion]
In file included from bitcoin_rpc.c:4:0:
/usr/include/string.h:42:14: note: expected ‘const void * restrict’ but argument is of type ‘short unsigned int’
 extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
              ^~~~~~
bitcoin_rpc.c:234:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     memcpy(&amp;number[1], (uint32_t)&amp;size, sizeof(uint32_t));
                        ^
bitcoin_rpc.c:234:24: warning: passing argument 2 of ‘memcpy’ makes pointer from integer without a cast [-Wint-conversion]
In file included from bitcoin_rpc.c:4:0:
/usr/include/string.h:42:14: note: expected ‘const void * restrict’ but argument is of type ‘unsigned int’
 extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
              ^~~~~~
bitcoin_rpc.c:238:24: warning: passing argument 2 of ‘memcpy’ makes pointer from integer without a cast [-Wint-conversion]
     memcpy(&amp;number[1], (uint64_t)&amp;size, sizeof(uint64_t));
                        ^
In file included from bitcoin_rpc.c:4:0:
/usr/include/string.h:42:14: note: expected ‘const void * restrict’ but argument is of type ‘long unsigned int’
 extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
</code></pre>

<block><c>
Implementation of the Variable length integer in C
Kleber Mota
# Implementation of the Variable length integer in C

(Asked by: username_0 on 2017-08-28)

Anyone can give me a idea of how implement in C this concept of Variable length integer which encoded the numer of transactions in a block? based on what is described [here](https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer), I think is something lime that:

```
if(value=?)
    uint8_t number_transactions = length;
else if(value=?)
    uint16_t number_transactions = 0xFD+length;
else if(value=?)
    uint32_t number_transactions = 0xFE_length;
else
    uint64_t number_transactions = 0xFF_length;

```

where `number_transactions` would be the value concatenated on the block. But how implement this? This [code](https://github.com/lemire/MaskedVByte/blob/master/src/varintencode.c) does the same described in the bitcoin wiki?

**UPDATE**

```
char* varint(unsigned long size) {
  char* number;
  if(size < 252) {
    number = malloc(1);
    number[0] = (uint8_t)size;
  } else if(size>=253 && size<65535) {
    number = malloc(3);
    number[0] = 0xfd;
    memcpy(&number[1], (uint16_t)&size, sizeof(uint16_t));
  } else if(size>=65536 && size<4294967295) {
    number = malloc(5);
    number[0] = 0xfe;
    memcpy(&number[1], (uint32_t)&size, sizeof(uint32_t));
  } else if(size>=4294967296) {
    number = malloc(9);
    number[0] = 0xff;
    memcpy(&number[1], (uint64_t)&size, sizeof(uint64_t));
  }
  return NULL;
}

```

message from compiler:

```
bitcoin_rpc.c: In function ‘varint’:
bitcoin_rpc.c:230:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     memcpy(&number[1], (uint16_t)&size, sizeof(uint16_t));
                        ^
bitcoin_rpc.c:230:24: warning: passing argument 2 of ‘memcpy’ makes pointer from integer without a cast [-Wint-conversion]
In file included from bitcoin_rpc.c:4:0:
/usr/include/string.h:42:14: note: expected ‘const void * restrict’ but argument is of type ‘short unsigned int’
 extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
              ^~~~~~
bitcoin_rpc.c:234:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     memcpy(&number[1], (uint32_t)&size, sizeof(uint32_t));
                        ^
bitcoin_rpc.c:234:24: warning: passing argument 2 of ‘memcpy’ makes pointer from integer without a cast [-Wint-conversion]
In file included from bitcoin_rpc.c:4:0:
/usr/include/string.h:42:14: note: expected ‘const void * restrict’ but argument is of type ‘unsigned int’
 extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
              ^~~~~~
bitcoin_rpc.c:238:24: warning: passing argument 2 of ‘memcpy’ makes pointer from integer without a cast [-Wint-conversion]
     memcpy(&number[1], (uint64_t)&size, sizeof(uint64_t));
                        ^
In file included from bitcoin_rpc.c:4:0:
/usr/include/string.h:42:14: note: expected ‘const void * restrict’ but argument is of type ‘long unsigned int’
 extern void *memcpy (void *__restrict __dest, const void *__restrict __src,

```

**Tags:** block, c


---

## 2 answers

### Answer by username_1 on 2017-08-28. Score: 1 | Accepted answer

No. The compact size unsigned integers are not uints (except for the base one of one byte). They are a serialization, so it is actually just an array of bytes. You just compare the number you are serializing to the boundaries and determine from there what the prefix byte is. Bitcoin.org does a better job of describing this: <https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers>. Note that you will need to understand hex numbers are and how they work in C.

> **Comments:**
> **username_0**: I implement a version of this method based on your sugestion, could you check if it's works? Also, there is some compiler warnings; do you have any sugestion of how to solve them?  
> **username_1**: You are casting pointers to uints. Don't do that since you are changing the pointer type, not the number type. Instead you should cast the variable first, then get a pointer to it or cast to a type pointer (e.g. uint32_t*)  

---

### Answer by username_2 on 2018-11-06. Score: 0

Here is [`libblkmaker`](https://github.com/bitcoin/libblkmaker/blob/master/blkmaker.c#L93)'s implementation:

```
static
char varintEncode(unsigned char *out, uint64_t n) {
    if (n < 0xfd)
    {
        out[0] = n;
        return 1;
    }
    char L;
    if (n <= 0xffff)
    {
        out[0] = '\xfd';
        L = 3;
    }
    else
    if (n <= 0xffffffff)
    {
        out[0] = '\xfe';
        L = 5;
    }
    else
    {
        out[0] = '\xff';
        L = 9;
    }
    for (unsigned char i = 1; i < L; ++i)
        out[i] = (n >> ((i - 1) * 8)) % 256;
    return L;
}

```


---

