On Saturday 30 October 2004 13:59, Tim Green wrote:
float l = 45.4567; float d = floorf(l); std::cout << "l-d = " << l - d << std::endl;
Basically, I getting an odd value printed for l - d (it comes out as 0.456699 and not 0.4567 as expected).
"float" is not that acurate. You might have more luck with "double".
Good luck! Tim.
Neither float nor double can truly represent some numbers. Just as 1/3 or 1/7 cannot be expressed exactly in decimal, some numbers - e.g. 0.1 - do not have an exact binary representation. Hence the tendency for the result to come back as a recurring decimal. Your numbers should never have gone to binary in the first place.
The solution depends on the environment. If you are dealing with financial quantities and never need to go better than one penny precision, you might consider using a large integer representing pennies, and adjust the position of the decimal point before printing. This doesn't completely do away with the problem but makes it acceptable in that context. Financial software rarely uses binary floating point; more commonly it uses a decimal form. In Java we have classes like BigDecimal for this purpose; no doubt there are C++ libraries to do a similar job.
Actually it's quite a minefield. BigDecimal has seven different rounding options, which is perhaps why my BT bill often computes the VAT to be a penny less than that given by my accounts program.
Interestingly (to me at least), in the days when we programmed everything in assembler, 8-bit microprocessors had a set of BCD (Binary Coded Decimal) instructions that allowed computations to mirror what we expect in real life. They were put there for use by pocket calculators, which is why these machines give the *right* answers and recur a third rather than a tenth. I expect the instructions are still there, but I doubt a C compiler makes use of them.
-- GT