Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tut] Convert Bytes To Floating Point Numbers

#1
Convert Bytes To Floating Point Numbers

<div><p class="has-background" style="background-color:#d6f7fc"><strong>Summary: </strong>The <code data-enlighter-language="generic" class="EnlighterJSRAW">struct</code> module in Python, taken from the C programming language, lets you convert <code data-enlighter-language="generic" class="EnlighterJSRAW">bytes</code> to and from <code data-enlighter-language="generic" class="EnlighterJSRAW">floating</code> point numbers.</p>
<hr class="wp-block-separator is-style-wide" />
<div id="ez-toc-container" class="ez-toc-v2_0_17 counter-hierarchy counter-decimal ez-toc-light-blue">
<div class="ez-toc-title-container">
<p class="ez-toc-title">Table of Contents</p>
<p><span class="ez-toc-title-toggle"><a class="ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle" style="display: none;"><i class="ez-toc-glyphicon ez-toc-icon-toggle"></i></a></span></div>
<nav>
<ul class="ez-toc-list ez-toc-list-level-1">
<li class="ez-toc-page-1 ez-toc-heading-level-2"><a class="ez-toc-link ez-toc-heading-1" href="https://blog.finxter.com/convert-bytes-to-floating-point-numbers/#A_Brief_Introduction_to_Struct" title="A Brief Introduction to Struct">A Brief Introduction to Struct</a>
<ul class="ez-toc-list-level-3">
<li class="ez-toc-heading-level-3"><a class="ez-toc-link ez-toc-heading-2" href="https://blog.finxter.com/convert-bytes-to-floating-point-numbers/#Definition_Of_Bytes_And_Floating_Point_Numbers" title="Definition Of Bytes And Floating Point Numbers">Definition Of Bytes And Floating Point Numbers</a></li>
</ul>
</li>
<li class="ez-toc-page-1 ez-toc-heading-level-2"><a class="ez-toc-link ez-toc-heading-3" href="https://blog.finxter.com/convert-bytes-to-floating-point-numbers/#Struct_Padding_vs_Packing" title="Struct Padding vs Packing">Struct Padding vs Packing</a></li>
<li class="ez-toc-page-1 ez-toc-heading-level-2"><a class="ez-toc-link ez-toc-heading-4" href="https://blog.finxter.com/convert-bytes-to-floating-point-numbers/#How_To_Use_The_Struct_Module_In_Python" title="How To Use The Struct Module In Python">How To Use The Struct Module In Python</a></li>
<li class="ez-toc-page-1 ez-toc-heading-level-2"><a class="ez-toc-link ez-toc-heading-5" href="https://blog.finxter.com/convert-bytes-to-floating-point-numbers/#Convert_Bytes_To_Floating_Point_Numbers" title="Convert Bytes To Floating Point Numbers">Convert Bytes To Floating Point Numbers</a></li>
<li class="ez-toc-page-1 ez-toc-heading-level-2"><a class="ez-toc-link ez-toc-heading-6" href="https://blog.finxter.com/convert-bytes-to-floating-point-numbers/#Conclusion" title="Conclusion">Conclusion</a></li>
</ul>
</nav>
</div>
<p><strong>Problem</strong>: How to convert bytes to floating point numbers?</p>
<p><strong>A quick look at the solution:</strong></p>
<figure class="wp-block-image size-full is-style-default"><img loading="lazy" width="839" height="228" src="https://blog.finxter.com/wp-content/uploads/2022/03/image-200.png" alt="" class="wp-image-259329" srcset="https://blog.finxter.com/wp-content/uploads/2022/03/image-200.png 839w, https://blog.finxter.com/wp-content/uplo...300x82.png 300w, https://blog.finxter.com/wp-content/uplo...68x209.png 768w" sizes="(max-width: 839px) 100vw, 839px" /></figure>
<h2><strong>A Brief Introduction to Struct</strong></h2>
<p>The <code>struct</code> module has three main methods for data conversion: </p>
<ul>
<li><code>unpack()</code>, </li>
<li><code>pack()</code></li>
<li><code>calcsize()</code>. </li>
</ul>
<p>➦ You can use the <code>unpack()</code> method to convert bytes to floating point numbers. The method accepts data format and the byte to be converted.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">struct.unpack("f", &lt;byte&gtWink</pre>
<p>➦ On the other hand, the <code>pack()</code> method helps in converting data types to bytes.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">struct.pack("f", &lt;floating point number&gtWink</pre>
<p>Where <code>f</code> stands for floats. As you will see in other parts of this tutorial, the <code>struct</code> module handles different data types such as characters, integers and floats. But before that, you should understand <code data-enlighter-language="generic" class="EnlighterJSRAW">bytes</code>, <code data-enlighter-language="generic" class="EnlighterJSRAW">floating point</code> numbers, and the concept of <code data-enlighter-language="generic" class="EnlighterJSRAW">structs</code>.</p>
<h3 class="has-large-font-size" style="font-style:normal;font-weight:700"><strong>Definition Of Bytes And Floating Point Numbers</strong></h3>
<p>This section focuses on the roots of bytes and data formats.</p>
<p>Unlike humans that represent numbers in base 10 (0 to 9 digits), computers understand the language of 1s and 0s. A pair of 1 and 0 is a binary digit, shortened as a bit. So, the computer converts data into a series of 1s and 0s (bits) before storing them in the memory.</p>
<p>Likewise, non-numerical data get stored as bytes. For instance, a character occupies 1 byte of memory. An array of characters forms a string.</p>
<figure class="wp-block-table">
<table>
<thead>
<tr>
<th>Format</th>
<th>Type in C programming language</th>
<th>size in bytes</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>c</code></td>
<td>char</td>
<td>1</td>
</tr>
<tr>
<td><code>b</code></td>
<td>signed char</td>
<td>1</td>
</tr>
<tr>
<td><code>B</code></td>
<td>unsigned char</td>
<td>1</td>
</tr>
<tr>
<td><code>?</code></td>
<td>_Bool</td>
<td>1</td>
</tr>
<tr>
<td><code>h</code></td>
<td>short</td>
<td>2</td>
</tr>
<tr>
<td><code>H</code></td>
<td>unsigned short</td>
<td>2</td>
</tr>
<tr>
<td><code>i</code></td>
<td>int</td>
<td>4</td>
</tr>
<tr>
<td><code>I</code></td>
<td>unsigned int</td>
<td>4</td>
</tr>
<tr>
<td><code>l</code></td>
<td>long</td>
<td>4</td>
</tr>
<tr>
<td><code>L</code></td>
<td>unsigned long</td>
<td>4</td>
</tr>
<tr>
<td><code>q</code></td>
<td>long long</td>
<td>8</td>
</tr>
<tr>
<td><code>Q</code></td>
<td>unsigned long long</td>
<td>8</td>
</tr>
<tr>
<td><code>s</code></td>
<td>char[]</td>
<td></td>
</tr>
<tr>
<td><code>f</code></td>
<td>float</td>
<td>4</td>
</tr>
</tbody>
</table>
</figure>
<p>Now that you understand how a computer interprets various data types, it would be best to learn how the struct module uses them to convert bytes to floating point numbers. Since struct has been taken from the C programming language, hence, a deeper understanding of how it works in C is crucial.</p>
<h2><strong>Struct Padding vs Packing</strong></h2>
<p>In the C programming language, a <code>struct</code> is a user-defined data type. Unlike other variables, a struct combines different data types in a structure. Here is an example.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">struct Fruit { char firstLetter; int total;
};</pre>
<p>We are creating a blueprint of a Fruit with a <code>firstLetter</code> character, and <code>total</code> integer. We can create a banana from the Fruit model, assigning it <em>b</em> as <code>firstLetter</code> and <em>23</em> as <code>total</code>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">struct Fruit fruit1 = { 'b', 23 };</pre>
<p>Printing the size of each attribute,</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">printf("firstLetter is %d bytes and total is %d bytes \n", sizeof(fruit1.firstLetter),sizeof(fruit1.number));</pre>
<p>we get the result as</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">firstLetter is 1 bytes and total is 4 bytes</pre>
<p>The size of fruit1 should be (1 + 4 =) 5 bytes, right? Let’s check.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Size of fruit1 is 8 bytes</pre>
<p>It turns out our computer uses more memory to store smaller data quantities. That happens due to a concept called <span style="text-decoration: underline">padding</span>.</p>
<p>CPU reads 4 bytes of data per cycle. For the first cycle, it adds three bytes of space to the available (1) byte and returns the result. Next, it finds 4 bytes and returns them. In total, it records (4 + 4 =) 8 bytes.</p>
<p>Padding wastes memory while reducing CPU cycles. Struct packing comes in to store more bytes in less memory.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#include &lt;stdio.h&gt;
#pragma pack(1) struct Fruit { char firstLetter; int number;
}; int main () { struct Fruit fruit1 = { 'b', 23 }; // printf("firstLetter is %d bytes and total is %d bytes \n", sizeof(fruit1.firstLetter),sizeof(fruit1.number)); printf("Size of fruit1 is %d bytes \n", sizeof(fruit1)); return 0;
}</pre>
<p>We include <code>#pragma pack(1)</code> header with <code>pack</code> function of value 1 to reduce the memory wastage when compiling and assembling data. This time around, the struct size is what we expect: 1 byte + 4 bytes = 5 bytes.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Size of fruit1 is 5 bytes </pre>
<p>The key takeaway is that struct is a C programming language data structure for storing user-defined data types. Unlike other data types, it combines a continuous stream of different data types. The various data types consume more memory due to padding, something we can control using struct packing.</p>
<p>We can apply the concept of struct to convert data types to bytes in Python, as illustrated below.</p>
<h2><strong>How To Use The Struct Module In Python</strong></h2>
<p>Unlike C, which speaks to the memory through data types and compiling, Python is a high-level, dynamically-typed programming language. Most operations occur through modules (classes) that get translated and compiled to produce bytes. One such module is the <code>struct</code> module.<br />The struct module has three methods: <code>pack()</code>, <code>unpack()</code>, and <code>calcsize()</code>. The pack method accepts two parameters: format and data to be converted to bytes. Like the struct blueprint in C, the format part of the pack function in Python accepts various data types. For example,</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">struct.pack('iif', 2, 4, 7.68)</pre>
<p>This means converting integer 2, integer 4 and float 7.68 to a stream of bytes. <code>i</code> stands for an integer while <code>f</code> represents floats.</p>
<p>You can represent repeating integers by a numeral. For example, <code>iii</code> can map to <code>3i</code>. Also, you can separate the data types with a space. For example, <code>3i f</code> is another representation for <code>3if</code>.</p>
<p>We can check the format size by importing the module,</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import struct </pre>
<p>and using its <code>calcsize()</code> method.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">struct.calcsize('3if')</pre>
<p>In the same way, we can convert a floating point number into bytes. Assume we want to convert 3.76 to bytes. We can do that using the following code.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">byteData = struct.pack('f', 3.76) print(byteData)</pre>
<p><strong>Output:</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">b'\xd7\xa3p@'</pre>
<p>Here, <code>b</code> stands for <code>bytes</code>. The other parts may differ as per computer depending on the memory address system and endianness. Let’s now find floating point numbers from bytes.</p>
<h2><strong>Convert Bytes To Floating Point Numbers</strong></h2>
<p>The unpack function accepts format, and the byte stream then converts it to a floating point number. For example, we can decode <code>b'\xd7\xa3p@'</code> as follows.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">byteData = struct.unpack('f', b'\xd7\xa3p@') print(byteData)</pre>
<p>The result is a tuple containing a floating point number with a massive number of decimal points.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">(3.759999990463257,)</pre>
<p>We can extract the result by surrounding the input with square brackets.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[byteData] = struct.unpack('f', b'\xd7\xa3p@')</pre>
<p>The result of printing the output is <code>3.759999990463257</code>.</p>
<p>The extended decimal output from a reduced input size shows the essence of scientific notation in computing. It also proves the reason for the preference of floating point numbers over integers.</p>
<p>Apart from efficiency, handling floating point numbers comes with speed since much work has gone into building floating point numbers over the years.</p>
<h2><strong>Conclusion</strong></h2>
<p>The struct module with its <code>unpack()</code> method helps convert bytes to floating point numbers. It would help to understand other methods such as <code>pack()</code> and <code>calcsize</code> because, from them, you can generate bytes from various data types.</p>
<p>Another way to ease handling the conversion is understanding the ins and outs of the struct module, as explained in this tutorial.</p>
<ul class="has-base-background-color has-background">
<li><strong>Recommended Reads:</strong>
<ul>
<li><strong><a rel="noreferrer noopener" href="https://blog.finxter.com/converting-integer-to-string-in-python/" target="_blank">Converting Integer to String in Python</a></strong></li>
<li><strong><a rel="noreferrer noopener" href="https://blog.finxter.com/python-string-to-float/" target="_blank">Python String to Float – A Simple Illustrated Guide</a></strong></li>
<li><strong><a href="https://blog.finxter.com/string-to-integer-python/">Converting String to Integer In Python</a></strong></li>
</ul>
</li>
</ul>
<hr class="wp-block-separator is-style-wide" />
<div class="wp-container-623bf76014c1f wp-block-buttons">
<div class="wp-block-button aligncenter"><a class="wp-block-button__link" href="https://academy.finxter.com/" target="_blank" rel="noreferrer noopener"><strong>FINXTER ACADEMY</strong></a></div>
</div>
<div class="wp-container-623bf76014f3f wp-block-buttons">
<div class="wp-block-button aligncenter"><a class="wp-block-button__link" href="https://blog.finxter.com/subscribe/" target="_blank" rel="noreferrer noopener"><strong>SUBSCRIBE</strong></a></div>
</div>
</div>


https://www.sickgaming.net/blog/2022/03/...t-numbers/
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

Forum software by © MyBB Theme © iAndrew 2016