3

I wanted to extract decimal places from decimal number. Not that hard, right?

So, I converted float to string.

Then, I used substr() to crop the string starting from string.find('.')+1, till the end.

Well.... the problem is here. When we have a number like this: 5.7741589, it's not "precise" that much, it's actually: 5.774159

If it round itself, I can't precisely get the number of decimal places... So question is:

How can I convert decimal number to string, without rounding it?

EDIT: Since a lot of people are asking for actual input and output and code, here it is:

Input: 5.7741589
Output (let's say we want to output just decimal places): 7741589
Output (not expected one): 774159

Code:

float num;
cin>>num;
string s = to_string(num);
s = s.substr(s.find('.')+1,s.length());
cout<<s<<endl;

EDIT2: One more thing. I need this for competitive programming, I can do this exercise with input as string. Imagine you have problem where you have 2 decimal numbers, you need to multiply them and then count number of decimal places. Then you again lose decimal places which is problem.

9
  • It’s unclear what you’re trying to accomplish, and what you’ve tried. Please post your actual code, and example input data and the desired output. Commented May 15, 2019 at 9:44
  • You're trying to use more decimal places than the de-facto float can store. Commented May 15, 2019 at 9:52
  • Please edit your question and add some examples of what you want. Also it's not clear what you're actually trying to achieve. Commented May 15, 2019 at 9:52
  • floats are usually binary numbers, with binary fractions (not decimal fractions). So when you say "decimal number", you're very likely wrong. A float can be converted to decimal exactly, but it may have a lot of digits. For example, the exact value of 2^-100 (this number can be easily stored in a float) has a lot of decimal digits. Commented May 15, 2019 at 9:55
  • To begin with: use double instead of float. Commented May 15, 2019 at 9:58

3 Answers 3

4

The rot sets in as soon as you use a binary floating point number to model a decimal number: a floating point scheme models a subset of the real numbers. In this respect it's no different to using an integral type: conceptually the issues that arise are no different.

If you want to model decimal numbers exactly then use a decimal type.

Sign up to request clarification or add additional context in comments.

Comments

1

The result you are getting is because of rounding off decimal places. This is because as soon as you enter a floating point number, whatever may be the number of decimal places, it is stored with as many decimal places as the precision of the data type. So for float (which can store 8 decimal places), if you enter

1.1234      ---- Stored as ---> 1.12339997
1.123       ---- Stored as ---> 1.12300003
5.7741589   ---- Stored as ---> 5.77415895

So basically, you are storing the input in those number (8) of decimal places. What can be done is that you can use below snippet to forcefully use the desired number of digits after decimal places and convert it to string.

float num;
cin >> num;

char buf[20];

// 8 is as per the (precision required + 1). So in this case,
// we have 7 digits after decimal, so 8 is used.
sprintf(buf, "%.8f", num); 

// Truncating the rounding off
buf[strlen(buf) - 1] = '\0';

string s(buf);
s = s.substr(s.find('.') + 1, s.length());
cout << s << endl;  

Though with this approach, it would be necessary that all your inputs are having equal number of decimal places.

This is sort of a workaround, because the value 5.7741589 that you entered is not stored as it is. So, if the source itself is not what you entered, how can you get the desired output with the assumption that source is what you provided.

1 Comment

"which can store 8 decimal places" - not necessarily.
1

Let's see what happens (this answer supposes IEEE-754, with floats being 32-bit binary floating-point numbers).

First, you enter the decimal number as input: 5.7741589. This number has to be stored into a 32-bit binary floating point.

This number in binary is 101.11000110001011110100011100010101011010000100011...

To store this into a float, we need to round it (in binary). So cin>>num is lossy. It is rounded to the nearest 32-bit binary floating point number, which is:

  • in binary: 1.01110001100010111101001 * 2^2 = 101.110001100010111101001.
  • in decimal: 1.44353973865509033203125 * 2^2 = 5.774158954620361328125.

As you can see, there is no point talking about decimal places, after your input number is converted to float, because your input number has been modified (looking at your number in binary, it got rounded. Looking at the number as decimal, it got a lot of extra digits, its value slightly differs from the original one).

If you want to solve this problem, you need to input the number as string, or you need to use some kind of decimal floating-point library.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.