{"id":1316,"date":"2014-05-14T16:15:28","date_gmt":"2014-05-14T13:15:28","guid":{"rendered":"http:\/\/vahamartti.fi\/blog\/?p=1316"},"modified":"2016-03-27T01:50:04","modified_gmt":"2016-03-26T22:50:04","slug":"perustarkkuuksisen-ieee-754-standardin-mukaisen-luvun-muuttaminen-liukuluvuksi","status":"publish","type":"post","link":"https:\/\/vahamartti.fi\/blog\/?p=1316","title":{"rendered":"Perustarkkuuksisen IEEE 754 standardin mukaisen luvun muuttaminen liukuluvuksi"},"content":{"rendered":"<p>T\u00e4ss\u00e4 blogauksessa k\u00e4sittelen perustarkkuuksisen IEEE 754 luvun muuttamista liukuluvuksi (reaaliluvuksi). Asian k\u00e4sittely juontaa juurensa er\u00e4\u00e4st\u00e4 modbus-v\u00e4yl\u00e4\u00e4n liitett\u00e4v\u00e4st\u00e4 laitteesta, jonka antamat tulokset normaaleilla muunnosoperaatiolla antoi k\u00e4sitt\u00e4m\u00e4tt\u00f6mi\u00e4 tuloksia.<\/p>\n<p>V\u00e4yl\u00e4lt\u00e4 saatu arvo piti saada muutetuksi reaaliluvuksi. V\u00e4yl\u00e4laitteelta saatu arvo oli esimerkiksi 402851D8h. Kun t\u00e4lle luvulle teki DWORD_TO_REAL muunnoksen, sai tulokseksi 1.076384 * 10^9, vaikka oikea arvo olisi ollut 2.6299953. Jokin siis m\u00e4tti ja pahasti.<\/p>\n<p>Selvisi, ett\u00e4 ABB AC500 logiikat \/ CoDeSys ohjelmointikieli ei tue liukulukumuunnosta natiivisti. Muunnosta ei siis voinut tehd\u00e4 DWORD_TO_REAL toimintoa k\u00e4ytt\u00e4en. Samalla selvisi, ettei sopivaa muunnospalikkaa ole ainakaan yleisesti saatavilla, joten sellainen oli teht\u00e4v\u00e4 itse. Mutta ennen muunnospalikan ohjelmoimista, oli tiedett\u00e4v\u00e4 miten IEEE 754 luku ylip\u00e4\u00e4t\u00e4\u00e4n muodostuu.<\/p>\n<p>IEEE 754 on liukulukustandardi, joka on yleisin tietokoneissa k\u00e4ytett\u00e4v\u00e4 liukulukustandardi. Satandardi m\u00e4\u00e4ritt\u00e4\u00e4 nelj\u00e4 erilaista liukulukua, erot liittyv\u00e4t n\u00e4ytt\u00f6tarkkuuteen ja lukualueen suuruuteen.<\/p>\n\n<table id=\"tablepress-5\" class=\"tablepress tablepress-id-5\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Nimi<\/th><th class=\"column-2\">Eng. nimi<\/th><th class=\"column-3\">Etumerkki<\/th><th class=\"column-4\">Exponentti<\/th><th class=\"column-5\">Desimaaliosa<\/th><th class=\"column-6\">Bias<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Puolitarkkuus<\/td><td class=\"column-2\">Half precision<\/td><td class=\"column-3\">1 [15]<\/td><td class=\"column-4\">5 [14-10]<\/td><td class=\"column-5\">10 [9-0]<\/td><td class=\"column-6\">15<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Perustarkkuus<\/td><td class=\"column-2\">Single precision<\/td><td class=\"column-3\">1 [31]<\/td><td class=\"column-4\">8 [30-23]<\/td><td class=\"column-5\">23 [22-0]<\/td><td class=\"column-6\">127<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Kaksoistarkkuus<\/td><td class=\"column-2\">Double precision<\/td><td class=\"column-3\">1 [63]<\/td><td class=\"column-4\">11 [62-52]<\/td><td class=\"column-5\">52 [51-0]<\/td><td class=\"column-6\">1023<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\"><\/td><td class=\"column-2\">Quadruple precision<\/td><td class=\"column-3\">1 [127]<\/td><td class=\"column-4\">15 [126-112]<\/td><td class=\"column-5\">112 [111-0]<\/td><td class=\"column-6\">16383<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<!-- #tablepress-5 from cache -->\n<p>Mittalaitteen antama tieto on kahden sanan pituinen, eli DWORD (32bit). Toisinsanoen mittatieto on perustakkuuksinen liukuluku. T\u00e4m\u00e4 tarkoittaa, ett\u00e4 31. bitti kertoo luvun <span style=\"color: #ff00ff;\">etumerkin<\/span>, seuraavat 8 bitti\u00e4 (bitit 30-23) kertovat <span style=\"color: #00ff00;\">exponentin<\/span> ja loput 23 bitti\u00e4 (bitit 22-0) <span style=\"color: #ff0000;\">desimaaliosan<\/span>. Muut tarkkuusluokat lasketaan saman periaatteen mukaisesti, mutta niiss\u00e4 on vain enemm\u00e4n\/v\u00e4hemm\u00e4n bittej\u00e4 ja tarkkuuluokkakohtainen bias. Allaolevaa ohjetta voi siis k\u00e4ytt\u00e4\u00e4 n\u00e4m\u00e4 seikat huomioonottaen my\u00f6s muissa tarkkuusluokissa.<\/p>\n<p>Muunnos tapahtuu seuraavasti:<\/p>\n<ol>\n<li>Muunnetaan DWORD, eli tuplasana, bin\u00e4\u00e4rimuotoon: 4028 51D8 h =&gt; 01000000 00101000 01010001 11011000 b<\/li>\n<li>Ryhmitell\u00e4\u00e4n edellinen bittijono kolmeen ryhm\u00e4\u00e4n, edell\u00e4kuvatun mukaisesti: <span style=\"color: #ff00ff;\">0<\/span> <span style=\"color: #00ff00;\">10000000<\/span> <span style=\"color: #ff0000;\">01010000101000111011000<\/span><\/li>\n<li>Luvun etumerkki m\u00e4\u00e4r\u00e4ytyy bitin 31 mukaan: 0 = positiivinen, 1 = negatiivinen. Koska bitti on t\u00e4ll\u00e4 kertaa <span style=\"color: #ff00ff;\">0<\/span>, on luku <span style=\"color: #ff00ff;\">positiivinen<\/span>.<\/li>\n<li>Seuraavasta ryhm\u00e4st\u00e4 lasketaan exponentti, joka on suora b =&gt; dec muunnos. Exponentti on siis <span style=\"color: #00ff00;\">10000000<\/span> b =&gt; <span style=\"color: #00ff00;\">128<\/span>.<\/li>\n<li>Koska luku on perustarkkuuksinen, on exponentin bias 127. T\u00e4ten lopulliseksi exponentiksi muodostuu 128 &#8211; 127 = 1.<\/li>\n<li>Seuraava vaihe, eli desimaaliosan laskenta on kaikkein ty\u00f6l\u00e4in prosessi koko muunnoksessa. Luku muodostuu 2-kantalukuisen negatiivisien potenssien summasta, potenssi m\u00e4\u00e4r\u00e4ytyy bitin paikan mukaan (eniten merkitsev\u00e4 bitti vasemmalla, v\u00e4hiten merkitsev\u00e4 oikealla). <span style=\"color: #ff0000;\">0<strong>1<\/strong>0<strong>1<\/strong>0000<strong>1<\/strong>0<strong>1<\/strong>000<strong>111<\/strong>0<strong>11<\/strong>000<\/span> b =&gt; 0*2^-1 + <strong>1*2^-2<\/strong> + 0*2^-3 + <strong>1*2^-4<\/strong> + 0*2^-5 + 0*2^-6 &#8230; =&gt; <strong>1\/4<\/strong> + <strong>1\/16<\/strong> + <strong>1\/1024<\/strong> &#8230; = <span style=\"color: #ff0000;\">0.314997673034668<\/span><\/li>\n<li>Lopullinen tulos lasketaan kaavalla (-1)^<span style=\"color: #ff00ff;\">etumerkkibitti<\/span> * (1 + <span style=\"color: #ff0000;\">desimaaliosa<\/span>) * 2^(<span style=\"color: #00ff00;\">exponentti <\/span>&#8211; bias) =&gt; (-1)^<span style=\"color: #ff00ff;\">0<\/span> *(1 + <span style=\"color: #ff0000;\">0.314997673034668<\/span>) * 2^(<span style=\"color: #00ff00;\">128 <\/span>&#8211; 127) = 2.62999534607<\/li>\n<li>Tulos on siis noin 2.63<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>T\u00e4ss\u00e4 blogauksessa k\u00e4sittelen perustarkkuuksisen IEEE 754 luvun muuttamista liukuluvuksi (reaaliluvuksi). Asian k\u00e4sittely juontaa juurensa er\u00e4\u00e4st\u00e4 modbus-v\u00e4yl\u00e4\u00e4n liitett\u00e4v\u00e4st\u00e4 laitteesta, jonka antamat tulokset normaaleilla muunnosoperaatiolla antoi k\u00e4sitt\u00e4m\u00e4tt\u00f6mi\u00e4 tuloksia. V\u00e4yl\u00e4lt\u00e4 saatu arvo piti saada muutetuksi reaaliluvuksi. V\u00e4yl\u00e4laitteelta saatu arvo oli esimerkiksi 402851D8h. Kun t\u00e4lle luvulle teki DWORD_TO_REAL muunnoksen, sai tulokseksi 1.076384 * 10^9, vaikka oikea arvo olisi ollut &hellip; <a href=\"https:\/\/vahamartti.fi\/blog\/?p=1316\" class=\"more-link\">Jatka lukemista <span class=\"screen-reader-text\">Perustarkkuuksisen IEEE 754 standardin mukaisen luvun muuttaminen liukuluvuksi<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[136,132,30],"tags":[137,138,280,135,134,279,133],"class_list":["post-1316","post","type-post","status-publish","format-standard","hentry","category-codesys","category-ohjelmointi","category-saatoa","tag-abb","tag-ac500","tag-codesys","tag-ieee-754","tag-liukuluku","tag-ohjelmointi","tag-plc"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1fteB-le","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1316","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1316"}],"version-history":[{"count":21,"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1316\/revisions"}],"predecessor-version":[{"id":1344,"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1316\/revisions\/1344"}],"wp:attachment":[{"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1316"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1316"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vahamartti.fi\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1316"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}