Lo que todo programador debería saber sobre aritmética de punto flotante
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

initial checkin

+311
+2
.gitignore
··· 1 + output 2 + tmp
+9
README.txt
··· 1 + floating-point.gui.de aims to provide both short and simple 2 + answers to the common recurring questions of novice programmers 3 + about floating point numbers not "adding up" correctly, and 4 + more in-depth information about how IEEE 754 floats work, 5 + when and how to use them correctly, and what to use instead 6 + when they are not appropriate. 7 + 8 + The site is build using the nanoc static site generator: 9 + http://nanoc.stoneship.org/
+1
Rakefile
··· 1 + require 'nanoc3/tasks'
+31
Rules
··· 1 + #!/usr/bin/env ruby 2 + 3 + # A few helpful tips about the Rules file: 4 + # 5 + # * The order of rules is important: for each item, only the first matching 6 + # rule is applied. 7 + # 8 + # * Item identifiers start and end with a slash (e.g. “/about/” for the file 9 + # “content/about.html”). To select all children, grandchildren, … of an 10 + # item, use the pattern “/about/*/”; “/about/*” will also select the parent, 11 + # because “*” matches zero or more characters. 12 + 13 + compile '/stylesheet/' do 14 + # don’t filter or layout 15 + end 16 + 17 + compile '*' do 18 + filter :erb 19 + filter :kramdown 20 + layout 'default' 21 + end 22 + 23 + route '/stylesheet/' do 24 + '/style.css' 25 + end 26 + 27 + route '*' do 28 + item.identifier + 'index.html' 29 + end 30 + 31 + layout '*', :erb
+41
config.yaml
··· 1 + # A list of file extensions that nanoc will consider to be textual rather than 2 + # binary. If an item with an extension not in this list is found, the file 3 + # will be considered as binary. 4 + text_extensions: [ 'css', 'erb', 'haml', 'htm', 'html', 'js', 'less', 'markdown', 'md', 'php', 'rb', 'sass', 'txt' ] 5 + 6 + # The path to the directory where all generated files will be written to. This 7 + # can be an absolute path starting with a slash, but it can also be path 8 + # relative to the site directory. 9 + output_dir: output 10 + 11 + # A list of index filenames, i.e. names of files that will be served by a web 12 + # server when a directory is requested. Usually, index files are named 13 + # “index.hml”, but depending on the web server, this may be something else, 14 + # such as “default.htm”. This list is used by nanoc to generate pretty URLs. 15 + index_filenames: [ 'index.html' ] 16 + 17 + # Whether or not to generate a diff of the compiled content when compiling a 18 + # site. The diff will contain the differences between the compiled content 19 + # before and after the last site compilation. 20 + enable_output_diff: false 21 + 22 + # The data sources where nanoc loads its data from. This is an array of 23 + # hashes; each array element represents a single data source. By default, 24 + # there is only a single data source that reads data from the “content/” and 25 + # “layout/” directories in the site directory. 26 + data_sources: 27 + - 28 + # The type is the identifier of the data source. By default, this will be 29 + # `filesystem_unified`. 30 + type: filesystem_unified 31 + 32 + # The path where items should be mounted (comparable to mount points in 33 + # Unix-like systems). This is “/” by default, meaning that items will have 34 + # “/” prefixed to their identifiers. If the items root were “/en/” 35 + # instead, an item at content/about.html would have an identifier of 36 + # “/en/about/” instead of just “/about/”. 37 + items_root: / 38 + 39 + # The path where layouts should be mounted. The layouts root behaves the 40 + # same as the items root, but applies to layouts rather than items. 41 + layouts_root: /
+40
content/basic.html
··· 1 + --- 2 + title: Basic Answers 3 + --- 4 + 5 + ### Why don't my numbers, like 0.1 + 0.2 add up to a nice round 0.3, and instead I get a weird result like 0.30000000000000004? 6 + 7 + Because internally, computers use a format ([binary floating point](/fp)) that 8 + cannot accurately represent a number like 0.1, 0.2 or 0.3 *at all*. 9 + When the code is compiled or interpreted, your "0.1" is already 10 + rounded to the nearest number in that format, which results 11 + in a slight error even before the calculation happens. 12 + 13 + ### Why do computers use such a stupid system? 14 + 15 + It's not stupid, just different. Decimal numbers cannot accurately 16 + represent a number like 1/3, so you have to round to 0.33 - and you 17 + don't expect 0.33 + 0.33 + 0.33 to result in 1, either. 18 + 19 + Computers use binary numbers because they're faster at dealing with 20 + those, and because for most calculations, a tiny error in the 17th 21 + decimal place doesn't matter at all since the numbers you work with 22 + aren't round (or that precise) anyway. 23 + 24 + ### What can I do to avoid this problem? 25 + 26 + That depends on what kind of calculations you're doing: 27 + 28 + * If you are doing technical calculations with short numbers and just don't want to end up with all those extra decimal places: simply [round your result](/rounding) to a fixed number of decimal places. 29 + * If you really need your results to add up exactly, especially when you work with money: use a special [decimal datatype](/decimal). Look at the "languages" section for details. 30 + * If you have no decimal datatype available, an alternative is to work with integers, e.g. do money calculations entirely in cents. But this is more work and has some drawbacks. 31 + 32 + 33 + ### Why do other calculations like 0.1 + 0.4 work correctly? 34 + 35 + In that case, the result (0.5) *can* be represented exactly as a floating point number, 36 + and the errors in the input numbers cancel each other out. 37 + 38 + In other cases like 0.1 + 0.3, the result actually isn't *really* 0.4, but close enough that 0.4 39 + is the shortest number that is closer to the result than to any other floating point number. Many languages then display that number instead of converting the actual result back to the closest 40 + decimal fraction.
+5
content/decimal.html
··· 1 + --- 2 + title: A New Item 3 + --- 4 + 5 + Hi, I'm a new item!
+6
content/fp.html
··· 1 + --- 2 + title: A New Item 3 + --- 4 + 5 + ![Obligatory xkcd cartoon](http://imgs.xkcd.com/comics/e_to_the_pi_minus_pi.png "Obligatory xkcd cartoon") 6 + How to mess with people who've come to *expect* rounding errors in floating point math.
+32
content/index.html
··· 1 + --- 2 + title: Home 3 + --- 4 + 5 + What Every Programmer Should Know About Floating-Point Arithmetic 6 + ================================================================= 7 + 8 + or 9 + -- 10 + 11 + Why don't my numbers add up? 12 + ============================ 13 + 14 + So you've written some innocent code, say for example: 15 + 16 + <pre> 17 + <a href="javascript:alert(0.1 + 0.2)">0.1 + 0.2</a> 18 + </pre> 19 + 20 + and got a really unexpected result: 21 + 22 + <pre> 23 + 0.30000000000000004 24 + </pre> 25 + 26 + You asked for help on some forum and got pointed to a [long article with lots of formulas](http://docs.sun.com/source/806-3568/ncg_goldberg.html) that didn't seem to help with your problem. 27 + 28 + Well, this site is here to: 29 + 30 + * Explain concisely why you get that unexpected result 31 + * Tell you how to deal with this problem 32 + * If you're interested, provide in-depth explanations of why floating point numbers have to work like that and what other problems can arise
+5
content/languages/csharp.html
··· 1 + --- 2 + title: A New Item 3 + --- 4 + 5 + Hi, I'm a new item!
+5
content/languages/java.html
··· 1 + --- 2 + title: A New Item 3 + --- 4 + 5 + Hi, I'm a new item!
+5
content/languages/javascript.html
··· 1 + --- 2 + title: A New Item 3 + --- 4 + 5 + Hi, I'm a new item!
+5
content/languages/php.html
··· 1 + --- 2 + title: A New Item 3 + --- 4 + 5 + Hi, I'm a new item!
+5
content/rounding.html
··· 1 + --- 2 + title: A New Item 3 + --- 4 + 5 + Hi, I'm a new item!
+86
content/stylesheet.css
··· 1 + * { 2 + margin: 0; 3 + padding: 0; 4 + 5 + font-family: Georgia, Palatino, Times, 'Times New Roman', sans-serif; 6 + } 7 + 8 + body { 9 + background: #fff; 10 + } 11 + 12 + #main { 13 + position: absolute; 14 + 15 + top: 40px; 16 + left: 280px; 17 + 18 + width: 700px; 19 + } 20 + 21 + #main h1 { 22 + font-size: 30px; 23 + font-weight: normal; 24 + 25 + line-height: 30px; 26 + 27 + letter-spacing: -1px; 28 + } 29 + 30 + #main p { 31 + margin: 20px 0; 32 + 33 + font-size: 15px; 34 + 35 + line-height: 20px; 36 + } 37 + 38 + #main ul { 39 + margin: 20px; 40 + } 41 + 42 + #main li { 43 + list-style-type: square; 44 + 45 + font-size: 15px; 46 + 47 + line-height: 20px; 48 + } 49 + 50 + #sidebar { 51 + position: absolute; 52 + 53 + top: 40px; 54 + left: 20px; 55 + width: 200px; 56 + 57 + padding: 20px 20px 0 0; 58 + 59 + border-right: 1px solid #ccc; 60 + 61 + text-align: right; 62 + } 63 + 64 + #sidebar h2 { 65 + text-transform: uppercase; 66 + 67 + font-size: 13px; 68 + 69 + color: #333; 70 + 71 + letter-spacing: 1px; 72 + 73 + line-height: 20px; 74 + } 75 + 76 + #sidebar ul { 77 + list-style-type: none; 78 + 79 + margin: 20px 0; 80 + } 81 + 82 + #sidebar li { 83 + font-size: 14px; 84 + 85 + line-height: 20px; 86 + }
+31
layouts/default.html
··· 1 + <!DOCTYPE HTML> 2 + <html lang="en"> 3 + <head> 4 + <meta charset="utf-8"> 5 + <title>The Floating-Point Guide - <%= @item[:title] %></title> 6 + <link rel="stylesheet" type="text/css" href="/style.css" media="screen"> 7 + <meta name="generator" content="nanoc 3.1.2"> 8 + </head> 9 + <body> 10 + <div id="main"> 11 + <%= yield %> 12 + </div> 13 + <div id="sidebar"> 14 + <h2>The Floating-Point Guide</h2> 15 + <ul> 16 + <li><a href="/">Home</a></li> 17 + <li><a href="/basic">Basic Answers</a></li> 18 + <li><a href="/fp">Floating Point</a></li> 19 + <li><a href="/decimal">Decimal types</a></li> 20 + <li><a href="/rounding">Rounding</a></li> 21 + </ul> 22 + <h2>Languages</h2> 23 + <ul> 24 + <li><a href="/languages/csharp">C#</a></li> 25 + <li><a href="/languages/java">Java</a></li> 26 + <li><a href="/languages/javascript">JavaScript</a></li> 27 + <li><a href="/languages/php">PHP</a></li> 28 + </ul> 29 + </div> 30 + </body> 31 + </html>
+2
lib/default.rb
··· 1 + # All files in the 'lib' directory will be loaded 2 + # before nanoc starts compiling.