# Thread: Why so much trouble with floating points?

1. ## Why so much trouble with floating points?

(I use borland c++ builder 5)

Lets say i want the number 1 devided by 4 = 0.25
i want my CSpinEdit to display this number.

So i tried CSpinEdit1->value = 0.25.

It doesn't work, my question is where do i find a cspinedit (or any other component) that supports large numbers of floating points? I tried BMSpinEdit, but it only supports 6 digits, my calculations go beyond it.

2. Maybe use standard functions?
Like sprintf() or std:: stuff.

3. The main consern is how to translate that into a floating value that gets displayed in spinedit?

4. Like maxorator suggests, you may want to convert the floating point to a string first, then display it.

5. float foo = 1;
std::stringstream ss;
ss << (foo / 4);

ss.Str(); // returns an std::string
ss.Str().c_str(); // returns a const char*

6. Ok, this stuf compiles in Borland builder

Edit1->Text = FloatToStr(1/5);

but the devision doesn't work.

if you say Edit1->Text = FloatToStr(1 - 0.34343);

the calculation does work.

Its vital that i can divide. Why doesn't it work?

7. 1 is an integer. So is 5. If you want floating point division, you have to mark the number as a floating point type. By default, floating point numbers use double in C++, so if you used 1.0 and 5.0 instead that would make them doubles and the division would work.

8. I want to thank you from the bottom of my heart,as it works -_-

It feels unnatural tho because every calculator on the planet can give a 1/5 = 0.2 result.

Am i wrong for thinking that such a basic calculation should also be possible with borland, regardless wether you'd be using an integer or not?

9. But dividing integers is a valid thing to do as well. If you are just doing integer arithmetic, you don't want something like 0.2. How does the compiler know the difference?

The designers of the language decided to identify which is which based on the types of the operands. Since 1 and 5 are ints, it does integer division. The calculator just assumes you always want floating point arithmetic and doesn't give you the choice, which is why it "works" there.

10. Anyway my list of problems doesn't seem to end.

im calculating 1.0/54.0 = 0.0185185185185185185 = not correct

Your ordinairy windows calculator would give 1/54 =

0.018518518518518518518518518518519

A longer number, i need to increase the amount of decimals displayed. I can't have any round off calculations, its important that it needs to be exactly like the number the windows calculator displays.

11. You need more precision. Unfortunately, it sounds like windows calculator provides more precision than the standard floating point types in C++. You should try it with long double instead of float, but I'm not sure about the Borland code you are using and how well it supports other types, and I get the feeling that the result will not be precise enough anyway. (BTW, for long double it would be 1.0L/5.0L).

In the end, if you really think you'll need larger precision, then you'll probably have to use a library that supports it. I think GMP might be one, but you can search for high precision floating point libraries.

>> I can't have any round off calculations
Windows calculator does rounding, it just does it later than the code you are using. You have to have rounding.

12. Ok, i've been messing around, but even the extended doesn't give more then 0.0185185185185185185

You know you have the FloatToDecimal function.

The Decimals parameter specifies the requested maximum number of digits to the left of the decimal point in the result. Precision and Decimals together control how the result is rounded. To produce a result that always has a given number of significant digits regardless of the magnitude of the number, specify 9999 for the Decimals parameter.

extern PACKAGE void __fastcall FloatToDecimal(TFloatRec &Result, const void *Value, TFloatValue ValueType, int Precision, int Decimals);

I have no idea how to use FloatToDecimal tho , So im wondering if it is possible to get a larger number out of FloatToDecimal , i've looked into your GMP suggestion, but it seems that library is rather Unix based then towards the windows enviroment im using (xp) , so if possible id like to go around that , and although not excluding any possibility, i would have hoped to get this larger decimal out of FloatToDecimal,

I can't find any good FloatToDecimal examples which could expand the number.

Im not picky i'll try any method that will give the 1/54 =

0.018518518518518518518518518518519 result.

13. But 1/54 is a recurrent decimal anyway.

The result being 0.0185185185185185185 and so on and so on. After you've printed 3 or 4 repeats, it gets pretty meaningless anyway.

> Im not picky i'll try any method that will give the 1/54 =
> 0.018518518518518518518518518518519 result.
Well it's not going to happen with any data type you're going to find on a PC without some help from a library.

A double has a precision of 15 decimal digits, so if you use any standard functionality, you get something like this.
Code:
```#include <stdio.h>

int main ( ) {
double f = 1.0 / 54.0;
long double g = 1.0l / 54.0l;
printf("%.15f\n", f );
printf("%.20f\n", f );
printf("%.18Lf\n", g );
printf("%.25Lf\n", g );
return 0;
}
\$ ./a.exe
0.018518518518519
0.01851851851851851749
0.018518518518518519
0.0185185185185185185188322```
In other words, trying to print anything beyond the precision of the underlying floating point format will just get you random noise.
A long double will get you another 3 decimal digits, but that's still way off the 30+ digits you seem to want.

Perhaps read up on what float can and cannot do, rather than basing your expectations on observation of windows calc.exe
http://en.wikipedia.org/wiki/Floating_point
http://docs.sun.com/source/806-3568/ncg_goldberg.html

14. Originally Posted by darketernal
Anyway my list of problems doesn't seem to end.

im calculating 1.0/54.0 = 0.0185185185185185185 = not correct

Your ordinairy windows calculator would give 1/54 =

0.018518518518518518518518518518519

A longer number, i need to increase the amount of decimals displayed. I can't have any round off calculations, its important that it needs to be exactly like the number the windows calculator displays.
Impossible. Without the source code to the Windows calculator, there is no way to be absolutely sure that in EVERY case the output is identical.
Don't forget, the Windows calculator suffers from inaccuracy just like every other calculator.
See what happens if you evaluate (2^0.5)^2 - 2 (where ^ signifies to-the-power-of). Note, the correct answer is zero.
The calculator can't represent every possible answer. It sure as hell can't represent numbers such as PI to infinite precision either!

Please state the reasons you would think you need it to be identical to the Windows calculator, and perhaps we can debunk a few myths for you.

15. ok, i founded a fitting solution. It seems that it all has to do with the value that is stored in the memory of the computer.

if in Borland i would use a floating point 1/255 = 0.00392156862745098

In windows calculator the result would be1/255 = 0.003921568627450980392156862745098

So i was thinking Lets recalculate (using windows calculator by saying 1/255 = 0.003921568627450980392156862745098 * 255 = 1

Borland would give. 255 * 0.00392156862745098 = 0.9999999999999999

You see, i had to get the value back on a solid 1 like in the windows calculator,instead of 0.99999999999999 this is why i was begging for more digits thinking it was a solid number, until someone pointed out that the number too was infinite , i didn't notice until then that the value gets stored in a odd manner.

For example.

If in (windows calculator) you say 1/255 = 0.003921568627450980392156862745098 * 255 = 1. This made me believe that it was an accurate number but its not, if you try typing

0.003921568627450980392156862745098 * 255 = (in your windows calculator) you get: 0.999999999999999999999999999975

So in order to get the accurate value, i basically applied the same trick as the windows calculator used by going backwards after going forward in Borland by using the same stored value to calculate instead of calculating with a result value i got the number 1 as i desired.

The windows calculators behaviour was basically the behaviour i desired for my program and i managed to do that so with this.

Thanks everyone. =)