home *** CD-ROM | disk | FTP | other *** search
/ stazsoftware.com / www.stazsoftware.com.tar / www.stazsoftware.com / futurebasic / tech-notes.php?v=7.orig < prev    next >
Text File  |  2010-08-22  |  11KB  |  352 lines

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  2. <html>
  3. <head>
  4. <title>Staz Software</title>
  5. <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  6. <style type="text/css">
  7.  
  8. body{
  9. background-color: #365488;
  10. border-top: 20px solid #365488;
  11. margin: 0px;
  12. }
  13.  
  14. a{
  15. color: #00f;
  16. text-decoration: none;
  17. }
  18.  
  19. a:hover{
  20. color: #00f;
  21. text-decoration: underline;
  22. }
  23.  
  24. p{
  25. margin: 0px;
  26. padding-left: 0px;
  27. padding-top: 0px;
  28. padding-right: 0px;
  29. padding-bottom: 10px;
  30. }
  31.  
  32. h1{
  33. font-size: 23px;
  34. padding-left: 2px;
  35. padding-top: 4px;
  36. padding-right: 5px;
  37. padding-bottom: 2px;
  38. margin-left: -2px;
  39. margin-top: 0px;
  40. margin-right: 0px;
  41. margin-bottom: 10px;
  42. background-color: #e7edf6;
  43. }
  44.  
  45. h2{
  46. font-size: 19px;
  47. padding: 0px;
  48. padding: 0px;
  49. margin-left: 0px;
  50. margin-top: 0px;
  51. margin-right: 0px;
  52. margin-bottom: 10px;
  53. }
  54.  
  55. h3{
  56. font-size: 15px;
  57. padding: 0px;
  58. margin-left: 0px;
  59. margin-top: 0px;
  60. margin-right: 0px;
  61. margin-bottom: 10px;
  62. }
  63.  
  64. hr{
  65. background-color: #b7bbc2;
  66. height: 1px;
  67. border: 0px;
  68. margin-top: 0px;
  69. margin-left: 0px;
  70. margin-bottom: 10px;
  71. margin-right: 0px;
  72. padding: 0px;
  73. }
  74.  
  75. span#pre,span.pre{
  76. color: #996633;
  77. font-size: 12px;
  78. font-family: monospace;
  79. }
  80.  
  81. pre{
  82. color: #996633;
  83. font-size: 12px;
  84. font-family: monospace;
  85. padding: 0;
  86. margin-left: 0px;
  87. margin-top: 0px;
  88. margin-right: 0px;
  89. margin-bottom: 10px;
  90. }
  91.  
  92. table.w{
  93. background-image: url('../graphics/site/window/middle.png');
  94. background-repeat: repeat-y;
  95. width: 880px;
  96. margin-left: auto;
  97. margin-right: auto;
  98. }
  99.  
  100. td.w-top{
  101. background-image: url('../graphics/site/window/top.png');
  102. background-repeat: no-repeat;
  103. padding-left: 15px;
  104. padding-right: 15px;
  105. text-align: center;
  106. height: 60px;
  107. min-height: 60px;
  108. font-size: 1px;
  109. line-height: 1px;
  110. }
  111.  
  112. td.w-middle{
  113. padding-top: 0px;
  114. padding-left: 15px;
  115. padding-right: 15px;
  116. vertical-align: top;
  117. }
  118.  
  119. td.w-bottom{
  120. background-image: url('../graphics/site/window/bottom.png');
  121. background-repeat: no-repeat;
  122. height: 25px;
  123. min-height: 25px;
  124. }
  125.  
  126. table.w-content{
  127. float: left;
  128. clear: none;
  129. border: 10px solid #e7edf6;
  130. width: 650px;}
  131.  
  132. td.w-content{
  133. border-left: 1px solid #cfd4dc;
  134. border-top: 1px solid #cfd4dc;
  135. border-right: 1px solid #b7bbc2;
  136. border-bottom: 1px solid #b7bbc2;
  137. padding-left: 20px;
  138. padding-top: 20px;
  139. padding-right: 20px;
  140. padding-bottom: 10px;
  141. background-color: #fff;
  142. vertical-align: top;
  143. min-height: 500px;
  144. }
  145.  
  146. table.w-sidebar{
  147. border-top: 10px solid #e7edf6;
  148. border-right: 10px solid #e7edf6;
  149. border-bottom: 10px solid #e7edf6;
  150. background-color: #e7edf6;
  151. width: 199px;
  152. float: right;
  153. clear: none;
  154. }
  155.  
  156. td.w-sidebar{
  157. border-left: 1px solid #cfd4dc;
  158. border-top: 1px solid #cfd4dc;
  159. border-right: 1px solid #b7bbc2;
  160. border-bottom: 1px solid #b7bbc2;
  161. background-color: #fff;
  162. text-align: center;
  163. padding-left: 10px;
  164. padding-top: 20px;
  165. padding-right: 10px;
  166. padding-bottom: 10px;
  167. }
  168.  
  169. td.w-sidebar img{
  170. border: 0px;
  171. }
  172.  
  173. table.w-tabs{
  174. background-image: url('../graphics/site/tabs/background.png');
  175. background-position: bottom center;
  176. height: 40px;
  177. margin-top: auto;
  178. }
  179.  
  180. td.w-tabs{
  181. text-align: center;
  182. vertical-align: bottom;
  183. }
  184.  
  185. td.w-tabs img{
  186. border: 0px;
  187. }
  188.  
  189. td.w-tabs a{
  190. border: 0px;
  191. }
  192.  
  193. input.text-box{
  194. border-left: 1px solid #b7bbc2;
  195. border-top: 1px solid #b7bbc2;
  196. border-right: 1px solid #cfd4dc;
  197. border-bottom: 1px solid #cfd4dc;
  198. background-color: #fff;
  199. }
  200.  
  201. input.push-button{
  202. border-left: 1px solid #cfd4dc;
  203. border-top: 1px solid #cfd4dc;
  204. border-right: 1px solid #b7bbc2;
  205. border-bottom: 1px solid #b7bbc2;
  206. background-color: #fff;
  207. }
  208. </style>
  209. </head>
  210. <body>
  211. <table class="w" border="0" cellpadding="0" cellspacing="0">
  212. <tr>
  213. <td class="w-top">
  214.  
  215. <img src="../graphics/site/window/title.png" alt="Staz Software">
  216. <table class="w-tabs" border="0" cellpadding="0" cellspacing="0" width="100%">
  217. <tr>
  218. <td class="w-tabs"><a href="../index.php"><img src="../graphics/site/tabs/home.png" alt="Home"></a><a href="../futurebasic/index.php"><img src="../graphics/site/tabs/active-futurebasic.png" alt="FutureBasic"></a><a href="../shareware/index.php"><img src="../graphics/site/tabs/shareware.png" alt="Shareware"></a><a href="../order/index.php"><img src="../graphics/site/tabs/order.png" alt="Order"></a><a href="../contact/index.php"><img src="../graphics/site/tabs/contact.png" alt="Contact"></a></td>
  219. </tr>
  220. </table>
  221. </td>
  222. </tr>
  223.  
  224. <tr>
  225. <td class="w-middle">
  226.  
  227. <table class="w-content" border="0" cellpadding="0" cellspacing="0">
  228. <tr>
  229. <td class="w-content">
  230. <h1>Tech Notes</h1><h2>Floating Point Math. Why doesn't .1 = .1?</h2><p>Older versions of FutureBASIC and ZBasic used a type of math called Binary Coded Decimal (BCD). This type of math was powerful and exact, but very slow. BCD math was really base 10 arithmetic. If we wanted to represent a number that number was represented exactly.</p>
  231.  
  232. <p>Modern math packages are “base 2” and are often referred to as binary math. Let’s start with a simple example that shows the difference between the two math packages.</p>
  233.  
  234. <pre>
  235. DIM myFloat1#,myFloat2#
  236.  
  237. myFloat1# = .1
  238. myFloat2# = FRAC(VAL("460.1"))
  239.  
  240. PRINT myFloat1#,myFloat2#
  241.  
  242. LONG IF myFloat1# = myFloat2#
  243.  BEEP   : REM Why doesn't this beep???
  244. END IF
  245. </pre>
  246.  
  247. <p>This isn’t rocket science. You can easily see that <span class="pre">myFloat1#</span> and <span class="pre">myFloat2#</span> are identical. It used to work OK in older version of FB (using the BCD math package). Yet there is no beep when the two are compared in FB. So what’s up with this?</p>
  248.  
  249. <p>The PPC math package used by FutureBASIC^3 does not work in base 10 as did BCD. It works in base two. To represent a number like 460.1, it needs three things:</p>
  250.  
  251. <ul>
  252. <li> the position of the decimal</li>
  253. <li> the information to the left of the decimal</li>
  254. <li> the information to the right of the decimal</li>
  255. </ul>
  256.  
  257. <p>In our simplified representation, the decimal position is the fourth character. the information to the left is a collection of bits which can be arranged to represent 460. Specifically:</p>
  258.  
  259. <pre>
  260. 460 = 
  261.  111001100 = 
  262.   (1*256) + (1*128) + (1 * 64) + (1 * 8) + (1 * 4)
  263. </pre>
  264.  
  265. <p>So far, everything is exact and we can’t see any room for error, but this is about to change. The only way numbers can be shown on the right hand side of the decimal is to build the reverse version of a binary number. A value must be made up of fractions like:</p>
  266.  
  267. <p><span class="pre">1/2 + 1/4 + 1/8 + 1/16 + 1/32</span> and so on</p>
  268.  
  269. <p>As with information to the left of the decimal, there are place holders for items not used. In other words, there is a zero bit if 1/2 is not added to the mix and a 1 bit if it is added to the mix.</p>
  270.  
  271. <p>In our specific example, the bits needed to link fractions together and come up with “.1” take up a big part of the allocated space for a floating point variable. (Try it yourself!) In fact, so much of the available 80 bits is consumed that there is no longer room for the “460” that goes to the left of the decimal. What can the system do?</p>
  272.  
  273. <p>At this point, the built-in math routines drop some of the very tiny decimals at the end of the list. (They are so small that they don’t matter anyway.) But in doing so, “.1” ends up being something like “.099999999999999” in the computer’s eyes.</p>
  274.  
  275. <p>Generally this is converted back to understandable numbers for you. For instance, if you print either of the “.1” values as we did in the example, you will see that Apple’s math package actually printed the correct value.</p>
  276.  
  277. <p>On the other hand, you can verify that two values which print as the same thing and logically seem to be the same are really different. Let’s make a small addition to the original example so that we can see what is stored in memory:</p>
  278.  
  279. <pre>
  280. DIM myFloat1#,myFloat2#
  281.  
  282. myFloat1# = .1
  283. myFloat2# = FRAC(VAL("460.1"))
  284.  
  285. PRINT myFloat1#,myFloat2#
  286.  
  287. LONG IF myFloat1# = myFloat2#
  288.  BEEP   : REM Why doesn't this beep???
  289. END IF
  290.  
  291. PRINT HEX$([@myFloat1#]);HEX$([@myFloat1#+4])
  292. PRINT HEX$([@myFloat2#]);HEX$([@myFloat2#+4])</span></span>
  293. </pre>
  294.  
  295. <p>Output:</p>
  296.  
  297. <pre>3FB999999999999A
  298. 3FB999999999A000
  299. </pre>
  300.  
  301. <p>Hold on. Let’s back up the hexadecimal choo choo here. These numbers are different, but when I print them with a print statement, they look the same!!</p>
  302.  
  303. <p>So here is a rule that you cannot side step or avoid. PPC math uses approximations of decimals that are usually, but not always, accurate. If you are going to make comparisons between floating point values that come from different types of operations, you are going to have to do things differently. Here are some thoughts on how you might change your current and future math coding.</p>
  304.  
  305. <p><strong>Don’t use floats for currency.</strong> If you are tracking money, there is no reason to use decimals for dollars (or pounds or yen or whatever). Use pennies instead. One dollar = 100 pennies. A long integer can hold a positive or negative amount of about 2 billion pennies. This translates to a range of -21,474,836.46 to +21,474,836.47. Unless your accounting package is going to top the 21 million dollar mark, you can use longs.</p>
  306.  
  307. <p><strong>Enlarge and convert to integers before comparing.</strong> If you have to compare floats that are created through different types of operations, multiply them and convert them first. Our example would have worked if we had done it as follows:</p>
  308.  
  309. <pre>LONG IF INT(myFloat1#*100) = INT(myFloat2#*100)</pre>
  310. </td>
  311. </tr>
  312. </table>
  313.  
  314. <table class="w-sidebar" border="0" cellpadding="0" cellspacing="0">
  315. <tr>
  316. <td class="w-sidebar">
  317. <p><a href="index.php"><img src="../graphics/fb_icon.png" alt="FutureBASIC"></a></p>
  318.  
  319. <p><a href="demo.php">Demo</a></p>
  320.  
  321. <p><a href="../order/index.php">Order</a></p>
  322.  
  323. <p><a href="tour.php">Tour</a></p>
  324.  
  325. <p><a href="tech-notes.php">Tech Notes</a></p>
  326.  
  327. <p><a href="faq.php">FAQ</a></p>
  328.  
  329. <p><a href="sample-code.php">Sample Code</a></p>
  330.  
  331. <p><a href="web-sites.php">Web Sites</a></p>
  332.  
  333. <p><a href="mailing-list.php">Mailing List</a></p>
  334.  
  335. <p><a href="system-requirements.php">System<br>Requirements</a></p>
  336.  
  337. <form method="GET" action="http://www.google.com/search" style="margin: 0; padding: 0;">
  338. <p style="margin: 0; padding: 0 0 5px 0; text-align: right;"><input type="hidden" id="ie" name="ie" value=UTF-8><input type="hidden" id="oe" name="oe" value=UTF-8><input type="text" name="q" size="15" maxlength="255" value="" style="width: 155px;" class="text-box"></p>
  339. <p style="margin: 0; padding: 0; text-align: right;"><input type="submit" name="btnG" value="Search" class="push-button"><input type="hidden" name="domains" value="stazsoftware.com"><input type="hidden" name="sitesearch" value=""><input type="hidden" name="sitesearch" value="stazsoftware.com" checked></p>
  340. </form></td>
  341. </tr>
  342. </table>
  343. </td>
  344. </tr>
  345.  
  346. <tr>
  347. <td class="w-bottom"><img src="../graphics/site/blank.gif" width="2" height="2" alt="blank"></td>
  348. </tr>
  349. </table>
  350.  
  351. </body>
  352. </html>