On 2017-11-09 10:01:45 +0100, Mason wrote: > > On 08/11/17 23:13 +0200, Nil Geisweiller wrote: > > > >> The following > >> > >> --------------------------------------------------------------------- > >> #include <iostream> > >> #include <cmath> > >> > >> int main() > >> { > >> double v = 4.6; > >> std::cout << "v = " << v << std::endl; > >> std::cout << "v*100 = " << v*100 << std::endl; > >> std::cout << "floor(v*100) = " << std::floor(v*100) << std::endl; > >> } > >> --------------------------------------------------------------------- > >> > >> outputs > >> > >> ------------------ > >> v = 4.6 > >> v*100 = 460 > >> floor(v*100) = 459 > >> ------------------ > >> > >> It that a bug? > > There is a boring and excruciatingly long paper floating (ha!) around: > "What Every Computer Scientist Should Know About Floating-Point Arithmetic" > https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html > > This other site tries to be more accessible: > http://floating-point-gui.de/ > > The short version is that it is not possible to represent 0.1 > (or any multiple thereof) in (fractional) base 2. Actually, that's mainly a language design bug, which doesn't show the error for 460 (which is representable exactly). > Basically, using "IEEE 754 double-precision binary floating-point format" > 4.6 is approximated as D=4.5999999999999996447286321199499070644378662109375 > ( https://en.wikipedia.org/wiki/Double-precision_floating-point_format ) > > Thus, it is obvious why floor(D*100) equals 459. No, this is not obvious. The multiplication by 100 introduces a rounding error. Thus this doesn't prove that the rounded value D*100 is strictly less than 460. -- Vincent Lefèvre <vincent@xxxxxxxxxx> - Web: <https://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)