{"id":18,"date":"2018-07-28T18:00:03","date_gmt":"2018-07-28T18:00:03","guid":{"rendered":"https:\/\/datablog.roman-halliday.com\/?p=18"},"modified":"2018-06-17T17:48:31","modified_gmt":"2018-06-17T17:48:31","slug":"danger-danger-float-value","status":"publish","type":"post","link":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/","title":{"rendered":"Danger! Danger! Float value!"},"content":{"rendered":"<p>I&#8217;m not saying that floating point numbers are the devil, and I&#8217;m not saying that the float data type should be avoided. But they should only be used when it&#8217;s entirely necessary and appropriate. The hidden danger of improper use can can become a ticking time bomb!<\/p>\n<p>Most (if not all) dangers come from FLOATs representing tiny fractions, rather than a value of 0.<\/p>\n<h1>When and why to use a FLOAT<\/h1>\n<p><a href=\"https:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright wp-image-19 size-medium\" src=\"https:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi-300x228.png\" alt=\"Three Thirds\" width=\"300\" height=\"228\" srcset=\"https:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi-300x228.png 300w, https:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi-355x270.png 355w, https:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi.png 537w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>The floating point number is an approximation of a number, it&#8217;s true power and use is in fractions. A classic case for fractions in computing is when we divide 1 by three, then add the result to itself three times (three thirds making a whole).<\/p>\n<p>The below example creates a value of 1 in the CTE. This value is stored in a temporary table, including dividing by three using both implicit and explicit type casting for comparison.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Drop the temp table if it exists\r\nIF OBJECT_ID('tempdb..#tmp_data') IS NOT NULL\r\n    DROP TABLE #tmp_data;\r\n\r\n-- Create a value of 1 (cast as a float)\r\n-- Then divide it by 3, storing the result as DECIMAL and as FLOAT\r\nWITH data_set AS (\r\nSELECT CAST(1 AS FLOAT) AS [value]\r\n)\r\nSELECT [value],\r\n       [value]\/3                        AS [value_d3],\r\n       CAST([value]\/3 AS DECIMAL(10,5)) AS [value_DEC],\r\n       CAST([value]\/3 AS FLOAT)         AS [value_FL]\r\n  INTO #tmp_data\r\n  FROM data_set\r\n;\r\n\r\n-- View the resulting numbers\r\nSELECT *\r\n  FROM #tmp_data\r\n;\r\n<\/pre>\n<table>\n<tbody>\n<tr>\n<th>value<\/th>\n<th>value_d3<\/th>\n<th>value_DEC<\/th>\n<th>value_FL<\/th>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>0.3333333333333333<\/td>\n<td>0.33333<\/td>\n<td>0.3333333333333333<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The results in that table will look largely consistent. The key difference between them will only come when we then want to multiply our thirds by three to get 1.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Multiply DECIMAL and FLOAT values by 3\r\nSELECT [value_DEC] * 3 AS [value_DEC_MULT],\r\n       [value_FL]  * 3 AS [value_FL_MULT]\r\n  FROM #tmp_data\r\n;<\/pre>\n<table>\n<tbody>\n<tr>\n<th>value_DEC_MULT<\/th>\n<th>value_FL_MULT<\/th>\n<\/tr>\n<tr>\n<td>0.99999<\/td>\n<td>1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The result for a DECIMAL value isn&#8217;t quite what we might expect. The float gives us a nice tidy 1, but the decimal gives us a little less than 1. This is because the DBMS is able to see that the float is an approximation of a third. But the decimal value is a literal 0.33333.<\/p>\n<p>So, use a FLOAT when we want a fraction to behave like a fraction. In all other cases, use an INTEGER or DECIMAL datatype.<\/p>\n<p>It&#8217;s worth looking at these examples in SQL Fiddle, SQL Server and Oracle behave the same, but MySQL returns a different result. The DBMS doesn&#8217;t realise that it&#8217;s looking at a third, and multiplies the fraction leaving us with a small variance. In this instance (and many like it) we can get around the variance by CASTing the result:<\/p>\n<ul>\n<li><a href=\"http:\/\/sqlfiddle.com\/#!18\/d4252\/2\" target=\"_blank\" rel=\"noopener\">SQL Fiddle &#8211; SQL Server<\/a><\/li>\n<li><a href=\"http:\/\/sqlfiddle.com\/#!4\/faa82\/1\" target=\"_blank\" rel=\"noopener\">SQL Fiddle &#8211; Oracle<\/a><\/li>\n<li><a href=\"http:\/\/sqlfiddle.com\/#!9\/ca5c94\/1\" target=\"_blank\" rel=\"noopener\">SQL Fiddle &#8211; MySQL<\/a><\/li>\n<\/ul>\n<h2>Danger 1, FLOATs are aproximate<\/h2>\n<p>As useful as a FLOAT is for fractions and for results of mathematical equations, remember that a FLOAT is an approximation, and not an actual number! Floating point numbers handle precision by effectively dropping off\u00a0 the most significant digits (for a fraction) or the least significant bits (for a large number), by shifting the decimal point and storing a range of the number.<\/p>\n<p>In most cases with a number over 30 digits long, the two least significant digits probably don&#8217;t carry much business meaning, but it&#8217;s a problem to be aware of (for example, if we are trying to get to Mars). With larger numbers, the addition (or subtraction) of a much smaller number can end up being ignored.<\/p>\n<p>Take the following example, where a small value is added to a large value, which is also subtracted from the total. A large value added to 50 then subtract the large value should equal 50. But in the first example it returns 0:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">                 --1234567890123456789012345678901234567890\r\nDECLARE @a FLOAT = 500000000000000000000000000000000000\r\nSELECT @a + 50 - @a -- Doesn't work as expected\r\nGO\r\n\r\n                 --1234567890123456789012345678901234567890\r\nDECLARE @a FLOAT = 500000000000000000000000000000000000\r\nSELECT @a - @a + 50 -- Works as expected\r\n\r\nGO\r\n\r\n                         --1234567890123456789012345678901234567890\r\nDECLARE @b DECIMAL(38,2) = 500000000000000000000000000000000000\r\nSELECT @b + 50 - @b -- Works as expected\r\n\r\nGO\r\n                         --1234567890123456789012345678901234567890\r\nDECLARE @b DECIMAL(38,2) = 500000000000000000000000000000000000\r\nSELECT @b - @b + 50 -- Works as expected\r\n\r\nGO<\/pre>\n<p>Results:<\/p>\n<p><a href=\"http:\/\/sqlfiddle.com\/#!18\/a83df\/1\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-35 size-full\" src=\"https:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/02\/SQL_Result_50.png\" alt=\"\" width=\"767\" height=\"676\" srcset=\"https:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/02\/SQL_Result_50.png 767w, https:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/02\/SQL_Result_50-300x264.png 300w, https:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/02\/SQL_Result_50-306x270.png 306w\" sizes=\"auto, (max-width: 767px) 100vw, 767px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/sqlfiddle.com\/#!18\/a83df\/1\" target=\"_blank\" rel=\"noopener\">SQL Fiddle &#8211; SQL Server: FLOAT Precision Problem Example<\/a><\/p>\n<h2>Danger 2, checking for a sum bigger than 0<\/h2>\n<p>There are stories of companies sending people bills which tell people that they are about to be cut off from a service for an unpaid bill, and that they must pay the outstanding balance of 0.00 immediately! Although the stories are often the stuff of <a href=\"https:\/\/www.snopes.com\/business\/bank\/zero.asp\">legend<\/a>, the cause is all too easy.<\/p>\n<p>A common cause of this is that a FLOAT is used to store financial values, and for example a percentage discount or fee is applied somewhere. When that happens it&#8217;s easy to add\/subtract numbers and end up with a tiny difference. This could be a non 0 value even though for all business reasons it should be 0.<\/p>\n<p>The below example shows a regular bill of 10.99, and then a subsequent one where there was a discount of 1\/3 applied (this is a simplified example of a bad way of doing things).<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"no-highlight\" data-enlighter-linenumbers=\"false\">NORMAL BILL\r\n------ ----\r\n    Bill: 10.99\r\n Payment: 10.99\r\n\r\nDISCOUNT BILL\r\n-------- ----\r\n    Bill: 10.99\r\n Payment:  7.33   -- Represented in the system as: 7.32666666666666 (two thirds)\r\nDiscount:  3.66   -- Represented in the system as: 3.66333333333333 (one third)\r\n<\/pre>\n<p>If we look at the amounts which people would see in bills below, the 7.33 and 3.66. We will get the 10.99 expected. However, when we use the floating point values, we get a result which should be 10.99 but isn&#8217;t quite (it&#8217;s off by an infinitely small decimal value).<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"no-highlight\" data-enlighter-linenumbers=\"false\">DECIMAL NUMBERS\r\n------- -------\r\n   7.33\r\n+  3.66\r\n  -----\r\n= 10.99\r\n\r\nFLOAT NUMBERS\r\n----- -------\r\n   7.32666666666666\r\n+  3.66333333333333\r\n  -----------------\r\n= 10.98999999999999<\/pre>\n<p>If a decimal value is used to store the results of the calculations then we lose the infinite recurring values.<\/p>\n<p>This example demonstrates the problem and the solution:<\/p>\n<ul>\n<li><a href=\"http:\/\/sqlfiddle.com\/#!18\/d4db8\/2\" target=\"_blank\" rel=\"noopener\">SQL Fiddle &#8211; SQL Server: Normal Bill<\/a><\/li>\n<li><a href=\"http:\/\/sqlfiddle.com\/#!18\/3cb71\/1\" target=\"_blank\" rel=\"noopener\">SQL Fiddle &#8211; SQL Server: Problem, Bill paid but FLOAT tracks tiny fraction<\/a><\/li>\n<li><a href=\"http:\/\/sqlfiddle.com\/#!18\/b5279\/1\" target=\"_blank\" rel=\"noopener\">SQL Fiddle &#8211; SQL Server: Problem fixed, using DECIMAL datatype<\/a><\/li>\n<\/ul>\n<p>Remember the classic maths\/computing joke, 1 + 1 = 3 (for large values of 1).<\/p>\n<h2>Danger 3, division by not quite 0<\/h2>\n<p>This is how I had a report billing for just over 70 trillion GBP! Sadly for me, the customer didn&#8217;t actually owe me that much cash.<\/p>\n<p>The danger here is when one divides a number by a small fraction, it results in a large multiplication. e.g.\u00a0 1\/0.000000001 =\u00a01,000,000,000<\/p>\n<p>If a value which should be 0, results in a FLOAT representing a small fraction, we get this error. This sort of multiplication can occur easily, and without warning.<\/p>\n<p>Another common cause for getting very small fractions, is subtracting a value which is nearly a fraction, from a value which is about a fraction (DECIMAL and FLOAT). We can end up with a number which is small enough that it should be 0, but instead it&#8217;s slightly higher (or lower) than 0.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Create a value of 1 (cast as a float)\r\n-- Then divide it by 3, storing the result as DECIMAL and as FLOAT\r\nWITH data_set AS (\r\nSELECT CAST(1 AS FLOAT) AS [value]\r\n)\r\nSELECT CAST([value]\/3 AS DECIMAL(10,5)) AS [value_DECIMAL],\r\n       CAST([value]\/3 AS FLOAT)         AS [value_FLOAT]\r\n  INTO tmp_data\r\n  FROM data_set\r\n;\r\n\r\n-- View the results of combining data types\r\nSELECT [value_DECIMAL],\r\n       [value_FLOAT],\r\n       [value_DECIMAL] - [value_DECIMAL] AS [result_DEC_sub_DEC],\r\n       [value_FLOAT]   - [value_FLOAT]   AS [result_FL_sub_FL],\r\n       [value_DECIMAL] - [value_FLOAT]   AS [result_DEC_sub_FL], -- Note that this should be 0, but it isn't\r\n       [value_FLOAT]   - [value_DECIMAL] AS [result_FL_sub_DEC]  -- Note that this should be 0, but it isn't\r\n  FROM tmp_data\r\n;\r\n\r\n-- Divide 1 by a fraction (created from combining data types)\r\nSELECT 1 \/ ([value_FLOAT]  - [value_DECIMAL]) AS [result_FL_sub_DEC]\r\n  FROM tmp_data\r\n;\r\n\r\n<\/pre>\n<p><a href=\"http:\/\/sqlfiddle.com\/#!18\/1438f\/2\" target=\"_blank\" rel=\"noopener\">SQL Fiddle &#8211; SQL Server: division danger<\/a><\/p>\n<h3>Solution 1<\/h3>\n<p>Cast the result of the subtraction as DECIMAL:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- View the results of combining data types\r\nSELECT [value_DECIMAL],\r\n       [value_FLOAT],\r\n       CAST([value_DECIMAL] - [value_FLOAT]   AS DECIMAL(10,4)) AS [DEC_result_DEC_sub_FL], -- This now returns 0\r\n       CAST([value_FLOAT]   - [value_DECIMAL] AS DECIMAL(10,4)) AS [DEC_result_FL_sub_DEC]  -- This now returns 0\r\n  FROM tmp_data\r\n;\r\n\r\n-- Divide 1 by a fraction (this time cast as DECIMAL), and including the NULLIF to avoid divide by 0 errors\r\nSELECT 1 \/ \r\n       NULLIF(CAST([value_FLOAT]   - [value_DECIMAL] AS DECIMAL(10,4)),\r\n              0) AS [result_FL_sub_DEC]\r\n  FROM tmp_data\r\n;<\/pre>\n<p><a href=\"http:\/\/sqlfiddle.com\/#!18\/1438f\/7\">SQL Fiddle &#8211; SQL Server: safe division by FLOATs<\/a><\/p>\n<h3>Solution 2<\/h3>\n<p>This is a little less elegant, but also saves any division by a value less than 1. Therefore we can&#8217;t end up with a multiplication.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- View the results of combining data types\r\nSELECT [value_DECIMAL],\r\n       [value_FLOAT],\r\n       [value_DECIMAL] - [value_FLOAT]   AS [result_DEC_sub_FL], -- Not 0, but a fraction\r\n       [value_FLOAT]   - [value_DECIMAL] AS [result_FL_sub_DEC]  -- Not 0, but a fraction\r\n  FROM tmp_data\r\n;\r\n\r\n-- Divide 1 by a fraction (this time cast as DECIMAL), and including the NULLIF to avoid divide by 0 errors\r\nSELECT CASE WHEN ([value_FLOAT]   - [value_DECIMAL]) &lt; 1\r\n            THEN NULL\r\n            ELSE 1 \/ ([value_FLOAT]   - [value_DECIMAL])\r\n        END AS [safe_result]\r\n  FROM tmp_data\r\n;<\/pre>\n<p><a href=\"http:\/\/sqlfiddle.com\/#!18\/1438f\/10\" target=\"_blank\" rel=\"noopener\">SQL Fiddle &#8211; SQL Server: Safe division by FLOATs using CASE<\/a><\/p>\n<h2>Danger 4, division by 0 error<\/h2>\n<p>This is now less common, more recent versions of SQL server appear to have patched this issue. I haven&#8217;t been able to recreate it. The cause is often the same as Danger 3 above (a value which should be 0 but isn&#8217;t).<\/p>\n<p>Commonly, to avoid divide by 0 errors, the value divided by is checked to see if it&#8217;s 0. If it is 0, the division is ignored. This is usually by setting the divisor to NULL (which causes a result of NULL), or using a WHERE condition to check for 0. The method is described in more detail here <a href=\"https:\/\/blog.sqlauthority.com\/2016\/08\/27\/sql-server-fix-error-8134-divide-zero-error-encountered\/\" target=\"_blank\" rel=\"noopener\">SQL SERVER \u2013 How to Fix Error 8134 Divide by Zero Error Encountered<\/a>.<\/p>\n<p>Just like checking for a value which is bigger than 0. There can be problems when checking if a value is 0!<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Check for divisor of 0\r\nSELECT CASE [value_to_divide_by]\r\n         WHEN 0 THEN 0\r\n         ELSE [value_to_divide]\/[value_to_divide_by]\r\n       END                                               AS [method_1_result],\r\n       [value_to_divide]\/NULLIF([value_to_divide_by], 0) AS [method_2_result]\r\n  FROM [db].[schema].[table \u201c\u201d not found \/]<br \/>\n\r\n;<\/pre>\n<p>This very rare problem comes up when one of the above methods decides that the number is not 0. So starts to perform the action. Then the computation decides that the number is 0 and as a result throws the error.<\/p>\n<h3>Solution<\/h3>\n<p>The simple solution (if one is faced with this problem) is to check for a very small number. Rather than checking for 0, check if the number is smaller than an arbitrary small number e.g.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">SELECT CASE WHEN [value_to_divide_by] &lt; 0.001 THEN 0 -- This keeps us safe from fractions which should be 0\r\n         ELSE [value_to_divide]\/[value_to_divide_by]\r\n       END                                               AS [method_3_result]\r\n  FROM [db].[schema].[table \u201c\u201d not found \/]<br \/>\n\r\n;<\/pre>\n<h1>Further reading<\/h1>\n<p>If interested, here is a very technical, but in depth article on floating point arithmetic (it&#8217;s based around Oracle, but the key information is consistent):\u00a0<a href=\"https:\/\/docs.oracle.com\/cd\/E19957-01\/806-3568\/ncg_goldberg.html\" target=\"_blank\" rel=\"noopener\">What Every Computer Scientist Should Know About Floating-Point Arithmetic<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m not saying that floating point numbers are the devil, and I&#8217;m not saying that the float data type should be avoided. But they should only be used when it&#8217;s entirely necessary and appropriate. The hidden danger of improper use can can become a ticking time bomb! Most (if not all) dangers come from FLOATs&hellip;<\/p>\n<p class=\"read-more\"><a class=\"readmore-btn\" href=\"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/\">Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,5,4],"tags":[7,8],"class_list":["post-18","post","type-post","status-publish","format-standard","hentry","category-databases","category-mysql","category-sql-server","tag-sql","tag-t-sql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Danger! Danger! Float value! - Rows Across The Lake<\/title>\n<meta name=\"description\" content=\"Floating point numbers aren&#039;t the devil, but they should only be used when it&#039;s entirely necessary and appropriate.\u00a0I have seen the float data type used in the wrong place, for the wrong reason, and it can become a ticking time bomb!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Danger! Danger! Float value! - Rows Across The Lake\" \/>\n<meta property=\"og:description\" content=\"Floating point numbers aren&#039;t the devil, but they should only be used when it&#039;s entirely necessary and appropriate.\u00a0I have seen the float data type used in the wrong place, for the wrong reason, and it can become a ticking time bomb!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/\" \/>\n<meta property=\"og:site_name\" content=\"Rows Across The Lake\" \/>\n<meta property=\"article:published_time\" content=\"2018-07-28T18:00:03+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi-300x228.png\" \/>\n<meta name=\"author\" content=\"david\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@d_roman_h\" \/>\n<meta name=\"twitter:site\" content=\"@d_roman_h\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"david\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/\"},\"author\":{\"name\":\"david\",\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/#\\\/schema\\\/person\\\/575f96d2590c3085923ff9e1b565748b\"},\"headline\":\"Danger! Danger! Float value!\",\"datePublished\":\"2018-07-28T18:00:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/\"},\"wordCount\":1225,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/#\\\/schema\\\/person\\\/575f96d2590c3085923ff9e1b565748b\"},\"image\":{\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/datablog.roman-halliday.com\\\/wp-content\\\/uploads\\\/2018\\\/01\\\/ThreeThirds-pi-300x228.png\",\"keywords\":[\"SQL\",\"T-SQL\"],\"articleSection\":[\"Databases\",\"MySQL\",\"SQL Server\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/\",\"url\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/\",\"name\":\"Danger! Danger! Float value! - Rows Across The Lake\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/datablog.roman-halliday.com\\\/wp-content\\\/uploads\\\/2018\\\/01\\\/ThreeThirds-pi-300x228.png\",\"datePublished\":\"2018-07-28T18:00:03+00:00\",\"description\":\"Floating point numbers aren't the devil, but they should only be used when it's entirely necessary and appropriate.\u00a0I have seen the float data type used in the wrong place, for the wrong reason, and it can become a ticking time bomb!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/#primaryimage\",\"url\":\"http:\\\/\\\/datablog.roman-halliday.com\\\/wp-content\\\/uploads\\\/2018\\\/01\\\/ThreeThirds-pi-300x228.png\",\"contentUrl\":\"http:\\\/\\\/datablog.roman-halliday.com\\\/wp-content\\\/uploads\\\/2018\\\/01\\\/ThreeThirds-pi-300x228.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/index.php\\\/2018\\\/07\\\/28\\\/danger-danger-float-value\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Danger! Danger! Float value!\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/#website\",\"url\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/\",\"name\":\"Rows Across The Lake\",\"description\":\"Data &amp; Databases\",\"publisher\":{\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/#\\\/schema\\\/person\\\/575f96d2590c3085923ff9e1b565748b\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/datablog.roman-halliday.com\\\/#\\\/schema\\\/person\\\/575f96d2590c3085923ff9e1b565748b\",\"name\":\"david\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/acddbc676a1d5c73795edcf0627ee39e5aa947da9033b58373e03d93122cb3b7?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/acddbc676a1d5c73795edcf0627ee39e5aa947da9033b58373e03d93122cb3b7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/acddbc676a1d5c73795edcf0627ee39e5aa947da9033b58373e03d93122cb3b7?s=96&d=mm&r=g\",\"caption\":\"david\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/acddbc676a1d5c73795edcf0627ee39e5aa947da9033b58373e03d93122cb3b7?s=96&d=mm&r=g\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Danger! Danger! Float value! - Rows Across The Lake","description":"Floating point numbers aren't the devil, but they should only be used when it's entirely necessary and appropriate.\u00a0I have seen the float data type used in the wrong place, for the wrong reason, and it can become a ticking time bomb!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/","og_locale":"en_GB","og_type":"article","og_title":"Danger! Danger! Float value! - Rows Across The Lake","og_description":"Floating point numbers aren't the devil, but they should only be used when it's entirely necessary and appropriate.\u00a0I have seen the float data type used in the wrong place, for the wrong reason, and it can become a ticking time bomb!","og_url":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/","og_site_name":"Rows Across The Lake","article_published_time":"2018-07-28T18:00:03+00:00","og_image":[{"url":"http:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi-300x228.png","type":"","width":"","height":""}],"author":"david","twitter_card":"summary_large_image","twitter_creator":"@d_roman_h","twitter_site":"@d_roman_h","twitter_misc":{"Written by":"david","Estimated reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/#article","isPartOf":{"@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/"},"author":{"name":"david","@id":"https:\/\/datablog.roman-halliday.com\/#\/schema\/person\/575f96d2590c3085923ff9e1b565748b"},"headline":"Danger! Danger! Float value!","datePublished":"2018-07-28T18:00:03+00:00","mainEntityOfPage":{"@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/"},"wordCount":1225,"commentCount":0,"publisher":{"@id":"https:\/\/datablog.roman-halliday.com\/#\/schema\/person\/575f96d2590c3085923ff9e1b565748b"},"image":{"@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/#primaryimage"},"thumbnailUrl":"http:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi-300x228.png","keywords":["SQL","T-SQL"],"articleSection":["Databases","MySQL","SQL Server"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/","url":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/","name":"Danger! Danger! Float value! - Rows Across The Lake","isPartOf":{"@id":"https:\/\/datablog.roman-halliday.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/#primaryimage"},"image":{"@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/#primaryimage"},"thumbnailUrl":"http:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi-300x228.png","datePublished":"2018-07-28T18:00:03+00:00","description":"Floating point numbers aren't the devil, but they should only be used when it's entirely necessary and appropriate.\u00a0I have seen the float data type used in the wrong place, for the wrong reason, and it can become a ticking time bomb!","breadcrumb":{"@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/#primaryimage","url":"http:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi-300x228.png","contentUrl":"http:\/\/datablog.roman-halliday.com\/wp-content\/uploads\/2018\/01\/ThreeThirds-pi-300x228.png"},{"@type":"BreadcrumbList","@id":"https:\/\/datablog.roman-halliday.com\/index.php\/2018\/07\/28\/danger-danger-float-value\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/datablog.roman-halliday.com\/"},{"@type":"ListItem","position":2,"name":"Danger! Danger! Float value!"}]},{"@type":"WebSite","@id":"https:\/\/datablog.roman-halliday.com\/#website","url":"https:\/\/datablog.roman-halliday.com\/","name":"Rows Across The Lake","description":"Data &amp; Databases","publisher":{"@id":"https:\/\/datablog.roman-halliday.com\/#\/schema\/person\/575f96d2590c3085923ff9e1b565748b"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/datablog.roman-halliday.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/datablog.roman-halliday.com\/#\/schema\/person\/575f96d2590c3085923ff9e1b565748b","name":"david","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/acddbc676a1d5c73795edcf0627ee39e5aa947da9033b58373e03d93122cb3b7?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/acddbc676a1d5c73795edcf0627ee39e5aa947da9033b58373e03d93122cb3b7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/acddbc676a1d5c73795edcf0627ee39e5aa947da9033b58373e03d93122cb3b7?s=96&d=mm&r=g","caption":"david"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/acddbc676a1d5c73795edcf0627ee39e5aa947da9033b58373e03d93122cb3b7?s=96&d=mm&r=g"}}]}},"_links":{"self":[{"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/posts\/18","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":22,"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/posts\/18\/revisions"}],"predecessor-version":[{"id":166,"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/posts\/18\/revisions\/166"}],"wp:attachment":[{"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/media?parent=18"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/categories?post=18"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/datablog.roman-halliday.com\/index.php\/wp-json\/wp\/v2\/tags?post=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}