Once I wrote a library for double-to-string conversion and vice versa, which handles such roundings nicely: https://github.com/mkupchik/dconvstr Key idea is not just to map binary floating point value X to a decimal floating point value Y, but instead (in extended precision, with 64-bit mantissa) compute an interval of decimal floating point values [Y1, Y2] which maps back to X (in standard precision, with 53-bit man…
The state-of-the-art is the Errol algorithm of Adrysco, Jhala and Lerner (2016), which is proven to be always correct: https://cseweb.ucsd.edu/~lerner/papers/fp-printing-popl16.pd...
0.30000000000000004
81–90 of 140 posts
Re: 0.30000000000000004
#82Earlier quoted context omitted.
Similarly, for C it could be: printf("%.*f\n", DBL_DECIMAL_DIG, .1+.2) In both cases, support for a relatively new language standard (C++11, C11) would be required.
2011 was six years ago.
Re: 0.30000000000000004
#83Once I wrote a library for double-to-string conversion and vice versa, which handles such roundings nicely: https://github.com/mkupchik/dconvstr Key idea is not just to map binary floating point value X to a decimal floating point value Y, but instead (in extended precision, with 64-bit mantissa) compute an interval of decimal floating point values [Y1, Y2] which maps back to X (in standard precision, with 53-bit man…
That's basically how Gay's dtoa works, and you'll find it copied into many projects—Python, for example, uses it for repr(). http://www.netlib.org/fp/dtoa.c
Re: 0.30000000000000004
#84Rexx has decimal arithmetics so 0.1+0.2 is 0.3 ... http://www.rexxla.org/events/2001/mike/rexxsy01.PDF
Unsurprising considering the IBM affiliation of Rexx and decimal arithmetic being IBM’s pet issue.
While IBM has been harping about this for ages, BCD (binary coded decimal) was sufficiently important that it had special instructions on even the earliest microprocessors. The 6800/8080/Z80 series had DAA (decimal adjust accumulator) and the 6502 had SED/CLD (set/clear decimal mode). The 8008 is notable in not having a specific BCD instruction.
And the 4004, which started it all, was a BCD oriented microprocessor from the start.
Re: 0.30000000000000004
#85Earlier quoted context omitted.
The state-of-the-art is the Errol algorithm of Adrysco, Jhala and Lerner (2016), which is proven to be always correct: https://cseweb.ucsd.edu/~lerner/papers/fp-printing-popl16.pd...
https://github.com/marcandrysco/Errol > Our original evaluation of Errol against the prior work of Grisu3 was erroneous. The evaluation indicates a 2x speed improvement over Grisu3. However, corrected performance measurements show a 2x speed loss to Grisu3.
Re: 0.30000000000000004
#86Re: 0.30000000000000004
#87Earlier quoted context omitted.
> Note that this will still not solve the 0.1 + 0.2 problem from the OP, since the nearest float to 0.3 is not actually the same as the nearest float to 0.1 + 0.2. Interval arithmetic can be used, although that requires double the storage for all the intermediate results, and extra work. For example, .1 can be represented by x=[x0, x1], where x0 and x1 are floating point values bracketing .1, and similarly .2 can be…
This unfortunately breaks with something like [+1, +1] / [-1, +1] which yields (-∞, -1] and [+1, +∞), the result falls into two separate intervals. Now you can either turn this into (-∞, +∞) or use sets of intervals instead of single intervals. The first option gives pretty useless results, the second one can become really slow and consume a lot of memory. You can make this work, but you have to be really careful wha…
Does it though? Wouldn't a result of `(-∞, +∞)` be a solid indication to go and reduce the range of your input parameters?
Re: 0.30000000000000004
#88It's actually pretty simple. When you have a base 10 system (like ours), it can only express fractions that use a prime factor of the base. In a way, not so simple (obvious to you? not to me)
FTFY
Re: 0.30000000000000004
#89Any time you're generating percentage data that should sum to 100, not appreciating floating point math will burn you. For those interested, the largest remainder method ( https://gist.github.com/hijonathan/e597addcc327c9bd017c ) is useful for dealing with this.
Using tricks to make numbers total what you think they "should" other than using rounding to proper amount of precision is lazy and deceitful.
Example: You're filling out a timesheet for a contracting job, and you worked 8 hours on several different tasks for your client, but your client's software rounds things to the nearest hour, then it would make sense to use an algorithm like this if your pay was going to be determined by this data entry. If your pay was not determined by this data entry then it may make sense to just round normally.
Re: 0.30000000000000004
#90Specifically, it's doing binary floating point math, which is an odd choice for decimal literals that's common only because very few languages choose correctness and clarity over performance when dealing with numbers, which leads to all kinds of problems with the most obvious approaches to addressing common problem domains in industrially popular languages. If I had a dollar for, well, every dollar of errors I'd seen because binary floating point values were used in a monetary calculation, I could afford to stop having to deal with them.