hello, for one of my programs I need to acquire the decimal off of a number, for example, if a double has value of "123.45" I need an int to have the value "45".

to do this, I have the following code

double value, tempValue;
int decimalValue;

value = 123.45
tempValue = value - floor(value);

while(tempValue != floor(tempValue)
{
          tempValue *= 10;
}

decimalValue = tempValue;

it does what it's supposed to, but for some reason doesn't get out of the loop when it should, here's the output of this loop:

"
tempValue: .45
floor(tempValue): 0

tempValue: 4.5
floor(tempValue): 4

tempValue: 45
floor(tempValue): 45

tempValue: 450
floor(tempValue): 450

etc..
"

it does this until tempValue = 4.5 x 10^15, then it breaks the loop. The only thing I can think of that would cause this is the fact that tempValue is a double, for example, it may say "45" on cout, but actually may hold the value of "45.00000000001"? any suggestions?

~J

Recommended Answers

All 5 Replies

you don't need a loop. Just multiplication and the mod operator will do it

int main()
{
    double n = 123.45;
    int x = (int)(n * 100);
    x = x % 100;
    cout << x << "\n";
}

I would do that, except I won't know how many decimals there are. I used "123.45" for my example, but it could be something on the order of "1.201923402". I guess I neglected to mention that it wouldn't be a constant as it is portrayed in the example, it is actually modified user input.

~J

You could use modf() to get the decimal portion. Then you can convert the decimal into a string using a stringstream. Then you can turn the string into a long.

Don't pursue mirages. Floating point arithmetics is binary, not decimal. Strictly speaking, no such double values as 0.45 or 0.1. Both real numbers are periodical binary fractions but it's impossible to represent infinite series of 0/1 exactly in 64-bit words (more precisely in 53 bits, see http://en.wikipedia.org/wiki/IEEE_754#Basic_formats).

All double values are approximations of correspondent real numbers with precision of ~15-16 decimal digits (all digits, not only fractional part). That's why your test was terminated after 15 loops.

Let we want to get 2 digits of fractional part as integer.

double x = 123.45; // it's ~0.45 (0.4499..X or 0.4500..Y)
int intfp2;
...
double intpart, fractpart;
fractpat = modf(x,&intpart); // fractpart ~= 0.45
fractpart *= 100.0;          // ~45.0
fractpart = floor(fractpart+0.5); // rounding to nearest int
intfp2 = static_cast<int>(fractpart);// == 45

Without addition 0.5 we have a risk to get 44 instead of 45.

Of course, you may use the same method for 1, 3 and so on fractional digits (multiply on 10, 1000 ... ). But you never get more than 15 fractional digits. Don't forget to convert a double value to positive number before split it to integral and fractional parts (use fabs or a simple conditional expression).

I hadn't thought of the stringstream, that's a good idea. It works quite nicely, thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.