{"id":1661,"date":"2020-10-08T10:25:08","date_gmt":"2020-10-08T08:25:08","guid":{"rendered":"https:\/\/zen-cori.138-201-132-86.plesk.page\/?p=1661"},"modified":"2022-09-06T09:54:58","modified_gmt":"2022-09-06T07:54:58","slug":"what-you-should-know-about-fixed-point","status":"publish","type":"post","link":"https:\/\/www.btc-embedded.com\/de\/what-you-should-know-about-fixed-point\/","title":{"rendered":"What You Should Know About Fixed-Point Code"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"1661\" class=\"elementor elementor-1661\" data-elementor-post-type=\"post\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-3b5f0493 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"3b5f0493\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-559a247a\" data-id=\"559a247a\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-7c099a8 elementor-widget elementor-widget-heading\" data-id=\"7c099a8\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Vocabulary: Floating-point code? - Fixed-point code? \u2013 Scaling? \u2013 Resolution? \u2013 LSB?<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a1ff07f elementor-widget elementor-widget-text-editor\" data-id=\"a1ff07f\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Basically, we can distinguish between two kinds of datatypes in embedded code:\u00a0<b>Floating-point<\/b>\u00a0and\u00a0<b>Integer<\/b>. An integer variable basically represents whole numbers and the value range is limited by the number of bits. For example, an (unsigned) 8bit Integer can represent 2^8=256 different values, by default ranging from 0 to 255. In contrast to this, a floating-point variable has some bits representing the significand and some bits representing the exponent in kind of scientific notation, which leads to a large data range.<\/p><figure class=\"content-image img_33 img_right\"><figcaption><\/figcaption><\/figure>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-19ece90 elementor-widget elementor-widget-image\" data-id=\"19ece90\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"800\" height=\"450\" src=\"https:\/\/www.btc-embedded.com\/wp-content\/uploads\/2020\/10\/fxp-blog-pics.001-1920x1920-c14.png\" class=\"attachment-large size-large wp-image-1665\" alt=\"Fixed-point Code with Resolution 0.01\" srcset=\"https:\/\/www.btc-embedded.com\/wp-content\/uploads\/2020\/10\/fxp-blog-pics.001-1920x1920-c14.png 1920w, https:\/\/www.btc-embedded.com\/wp-content\/uploads\/2020\/10\/fxp-blog-pics.001-1920x1920-c14-768x432.png 768w, https:\/\/www.btc-embedded.com\/wp-content\/uploads\/2020\/10\/fxp-blog-pics.001-1920x1920-c14-1536x864.png 1536w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-934b48a elementor-widget elementor-widget-text-editor\" data-id=\"934b48a\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>But what is fixed-point?\u00a0<b>Fixed-point<\/b>\u00a0is a special type of Integer variables, which have a scaling. So what\u2019s\u00a0<strong>S<\/strong><b>caling<\/b>? It means that the resolution is not 1 but rather another value defined by the user. But what\u2019s\u00a0<strong>Resolution<\/strong>? It is the difference between two values if just the last bit is changing. That\u2019s why sometimes the resolution is also called\u00a0<b>LSB<\/b>, which means \u201cleast significant bit\u201d. (Fun fact: In France they call scaling \u201cmise \u00e0 l\u2019echelle\u201d which translates to \u201cputting it on a ladder\u201d. Much easier to visualize this way).<\/p><p>As a result, for fixed-point variables we can distinguish between a physical value and an integer value. As there is also the possibility to define an offset, the formula looks like this:<\/p><p><i>Physical Value = Integer Value * Resolution + Offset<\/i><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6cdaf06 elementor-widget elementor-widget-text-editor\" data-id=\"6cdaf06\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<div class=\"content-box__grey\"><p>As an example, let\u2019s look at two variables which have different scalings (second fun fact: In France, variables in a code example are not called\u00a0<i>foo<\/i>\u00a0and\u00a0<i>bar<\/i>\u00a0but\u00a0<i>toto<\/i>\u00a0and\u00a0<i>titi<\/i>. Yes. It\u2019s true.):<\/p><ul><li><i>toto<\/i>\u00a0has a resolution of 0.1, so a physical value of 15 would lead to an integer value of 150<\/li><li><i>titi<\/i>\u00a0has a resolution of 0.5, so a physical value of 12 would lead to an integer value of 24<\/li><\/ul><p>If we want to combine these two variables in a mathematic operation in our production code, we would first need to align the scaling, also taking the scaling of the target variable into account. Let\u2019s build a sum and store the result in a variable\u00a0<i>result\u00a0<\/i>which has a resolution of 0.1:<\/p><p><i>result= toto + titi*5<\/i><\/p><\/div>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6ec190f elementor-widget elementor-widget-text-editor\" data-id=\"6ec190f\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>This means, that in order to calculate the sum, we also have to perform a multiplication. This is why for optimization reasons, resolutions are sometimes defined as a power of two (e.g. 2<sup>-3\u00a0<\/sup>). In this case, all the additional multiplications coming from adapting the resolution can be implemented using bitshift operations (e.g. going from 2<sup>-2<\/sup>\u00a0to 2<sup>-5<\/sup>\u00a0can be implemented realized by shifting the bits 3 digits to the left:\u00a0<i>titi&lt;&lt;3<\/i>).<\/p><p>One more thing:\u00a0<b>Ranges<\/b>\u00a0and\u00a0<b>Headroom<\/b>. Whenever we define a scaling\/resolution together with a corresponding integer datatype, we also define how we represent this value range. Let\u2019s say we have an Int8 Datatype and want to represent a temperature which can be between 0\u00b0 and 25\u00b0. We can then pick a resolution of LSB=0,1 which lead to a data range of min=0\u00b0 and max=25,5\u00b0. But what if the actual value gets higher than 25,5\u00b0? This could happen for multiple reasons, maybe we underestimated the maximum value of this variable or maybe there is just some noise on the sensor signal. If the value gets higher, an overflow occurs which should be avoided.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-da6f93a elementor-widget elementor-widget-heading\" data-id=\"da6f93a\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Finding the right scaling = Picking between three optimization goals<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fa217fc elementor-widget elementor-widget-text-editor\" data-id=\"fa217fc\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>So how do you find the best scaling for your application? The sad news is, that there is no such thing as the ideal scaling. The task of scaling fixed-point code is always a compromise between three different goals which can never be achieved at the same time. And, it\u2019s a compromise we are not just making once for the whole application, but per variable.<\/p><p>\u00a0<\/p><ol><li>Precision: Optimizing the precision of our calculations can be achieved by making the resolution as small as possible. First of all, we can make the resolution small if we pick an integer datatype with a lot of different states (e.g. Int32 with 2^32 different values). But compared to 8bit or 16bit data types, this would require more processing power which will have a negative impact on performance. We can also reduce the resolution if we choose a small headroom, but this makes the risk for overflows higher.<\/li><li>Performance: If we want to get the best performance, we might pick an Int8 datatype, sacrificing on precision.<\/li><li>Headroom: Optimizing for headroom means to make the implemented value range much larger than the expected min\/max values. But as discussed before, increasing the data range will have a negative impact on the resolution and therefore on the precision.<\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-aadfa40 elementor-widget elementor-widget-image\" data-id=\"aadfa40\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"800\" height=\"450\" src=\"https:\/\/www.btc-embedded.com\/wp-content\/uploads\/2020\/10\/fxp-blog-pics.002-1920x1920-c14.png\" class=\"attachment-large size-large wp-image-1668\" alt=\"The task of scaling fixed-point code is always a compromise between three different goals which can never be achieved at the same time.\" srcset=\"https:\/\/www.btc-embedded.com\/wp-content\/uploads\/2020\/10\/fxp-blog-pics.002-1920x1920-c14.png 1920w, https:\/\/www.btc-embedded.com\/wp-content\/uploads\/2020\/10\/fxp-blog-pics.002-1920x1920-c14-768x432.png 768w, https:\/\/www.btc-embedded.com\/wp-content\/uploads\/2020\/10\/fxp-blog-pics.002-1920x1920-c14-1536x864.png 1536w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d88eb76 elementor-widget elementor-widget-heading\" data-id=\"d88eb76\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">How to handle fixed-point code efficiently<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e9bd924 elementor-widget elementor-widget-text-editor\" data-id=\"e9bd924\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<ol><li><b>Use a code generator<\/b><\/li><\/ol><p>If we have to handle different variables with different scaling in our application, it can become quite challenging to manually define all the additional scaling operations (like multiplications and or bitshifts). Using an automatic code generator like <a href=\"https:\/\/www.btc-embedded.com\/test_environments\/dspace-targetlink\/\">dSPACE TargetLink<\/a> or <a href=\"https:\/\/www.btc-embedded.com\/test_environments\/mathworks-embedded-coder\/\">Embedded Coder<\/a>, allows us to focus on defining our algorithm in the physical domain while the code generator takes care of the fixed-point code operations. It\u2019s also very easy to automatically update the code should the scaling of one or more of the variables change. For handwritten code, we\u2019d need to identify all locations in the code where these variables are used in order to modify them.<\/p><ol start=\"2\"><li><b>Get some help to find the right scaling<\/b><\/li><\/ol><p>There are mainly two techniques to (at least partially) automate the scaling configuration (e.g. provided by dSPACE TargetLink). The first one is range propagation. Based on user-defined input ranges and data types, the algorithm will try to calculate the worst-case ranges of all internal variables and set the scaling accordingly. For example, if our algorithm calculates the sum of two inputs with range [0 10], the variable for the result would get a worst-case range of [0 20]. This approach has risk of making the implemented ranges too large (because maybe the \u201cworst case\u201d of both inputs having the value 10 at the same time doesn\u2019t occur). The second approach is simulation based. It uses test cases which are executed to observe the min\/max values of each variable. This approach comes with the risk of making the implemented ranges too small, as maybe the test cases do not cover all possible ranges.<\/p><ol start=\"3\"><li><b>Make sure that your test tool allows you to work with physical values<\/b><\/li><\/ol><p>When working with fixed-point variables, it\u2019s possible for a physical value of 25\u00b0 to be represented by an integer value of 250 (with a resolution of LSB=0,1) or 800 (with a resolution of LSB=2<sup>-5<\/sup>). When writing a test case (or reviewing results), it\u2019s always much easier to work with physical values as these are also the ones typically used in the requirements. So, our test tool should be able to represent both the physical values AND convert the value to the corresponding integer representation for code based simulations.<\/p><figure class=\"content-image \"><\/figure>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3810d50 elementor-widget elementor-widget-heading\" data-id=\"3810d50\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Come on, it\u2019s 2020! Shouldn\u2019t we all be doing floating-point code by now?<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6bb1d04 elementor-widget elementor-widget-text-editor\" data-id=\"6bb1d04\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Not so fast. It is clearly true, that some years ago developers didn\u2019t have much choice. Due to limited processing power and missing floating-point units in common embedded processors, the code had to be implemented in fixed-point. Today, many processors can handle floating-point and many developers believe that life gets easier. But there are also some misunderstandings when it comes to floating-point.<\/p><p>First, let\u2019s acknowledge that floating-point variables do not have perfect mathematical accuracy, and in fact they also have a resolution. But, in contrast to fixed-point code, this resolution can\u2019t be configured and it is not the same over the whole value range. For very large numbers the resolution actually is worse than for integer. So, if you have variables working in a clearly defined data range, fixed-point gives you actually more freedom to define and optimize the precision compared to floating-point.<\/p><p>Second, from a verification point of view, the mathematics of floating-point operations are often harder to understand and to debug compared to fixed-point. We can even have a different behavior depending on the compiler, which is typically not the case for fixed-point. Check out our blog article \u201c<a href=\"https:\/\/www.btc-es.de\/en\/blog\/what-you-should-know-about-floating-point.html\" target=\"_blank\" rel=\"noopener\">What you should know about floating-point<\/a>\u201d for more details.<\/p><figure class=\"content-image \"><\/figure>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-620c7ed elementor-widget elementor-widget-heading\" data-id=\"620c7ed\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Conclusion<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5539473 elementor-widget elementor-widget-text-editor\" data-id=\"5539473\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Fixed-point code basically uses integer datatypes together with a scaling. The scaling and the offset define the resolution of the variable leading to the physical value range which can be represented. Finding the right scaling means finding a compromise between precision, performance and headroom. By using a code generator like dSPACE TargetLink, we can get some help implementing the fixed-point operations in the production code and we can also get some help to find the right scaling. If we use floating-point variables, we can get rid of the scaling task, but this creates new challenges due to the fact that floating-point behavior can often be less transparent and predictable as compared to fixed-point.<\/p><figure class=\"content-image \"><\/figure>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Vocabulary: Floating-point code? &#8211; Fixed-point code? \u2013 Scaling? \u2013 Resolution? \u2013 LSB? Basically, we can distinguish between two kinds of datatypes in embedded code:\u00a0Floating-point\u00a0and\u00a0Integer. An integer variable basically represents whole numbers and the value range is limited by the number of bits. For example, an (unsigned) 8bit Integer can represent 2^8=256 different values, by default [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":9032,"comment_status":"open","ping_status":"closed","sticky":false,"template":"elementor_theme","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[50,49,48,51],"product":[],"use_cases":[],"class_list":["post-1661","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-automatic-code-generation","tag-model-based-development","tag-simulink","tag-targetlink"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/posts\/1661","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/comments?post=1661"}],"version-history":[{"count":0,"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/posts\/1661\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/media\/9032"}],"wp:attachment":[{"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/media?parent=1661"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/categories?post=1661"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/tags?post=1661"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/product?post=1661"},{"taxonomy":"use_cases","embeddable":true,"href":"https:\/\/www.btc-embedded.com\/de\/wp-json\/wp\/v2\/use_cases?post=1661"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}