user586399
user586399

Reputation:

Getting the decimal point value

I have a function which should covert a double value into string one:

inline static string StringFromNumber(double val) // suppose val = 34.5678
{
 long integer = (long)val; // integer = 34
 long pointPart; // should be = 5678  how do I get it?
}

How do I get a long value for both integer and pointPart?

Add: I want a precision of 17 numbers, with discarding the zeros. More examples:

val = 3.14 integer = 3 pointPart = 14

val = 134.4566425814748 integer = 134 pointPart = 4566425814748

I have not got any solution so far. How can I get it?

Upvotes: 1

Views: 819

Answers (3)

Jason
Jason

Reputation: 32490

You can use modf to separate the integer and fractional parts. You can then multiply the fractional part by 1.0e17, and call floor to properly round the results to it's integer component, and then cast to a unsigned long (the fractional part will never be negative, and this allows you to maximize the number of bits in the integral type). Finally run though a loop to trim off the zeros on the unsigned long. For instance:

inline static string StringFromNumber(double val)
{
    double intpart, fracpart;
    fracpart = round((modf(val, &intpart)) * 1.0e17);

    long int_long = static_cast<long>(intpart);
    unsigned long frac_long = static_cast<long>(fracpart);

    //trim off the zeros
    for(unsigned long divisor = 10;;divisor *= 10)
    {
        if ((frac_long / divisor) * divisor != frac_long)
        {
            frac_long = frac_long / (divisor / 10);
            break;
        }
    }

    //...more code for converting to string
}

Note that this code will only work up to 17 decimal places if you are on a 64-bit platform and unsigned long is defined as a 64-bit integer-type. Otherwise you will want to change unsigned long to uint64_t. Also keep in mind that since floating point numbers are approximations, and there's a multiplier by 1.0e17, the value of fracpart may not be exactly the value of the point-part of val ... in other words there may be some additional digits after any necessary rounding.

Upvotes: 1

SD1990
SD1990

Reputation: 808

long pointPart = static_cast<long>(val*10)%10;

10 for 2 decimal places... 100 for 3 etc...

String realPoint = (string)pointPart;

Plus long connot hold 17 digits. it holds 10. so you probably want a float variable

Upvotes: 2

jwfriese
jwfriese

Reputation: 228

A stringstream won't get you the decimal point in particular, but it will convert the entire number to a string.

std::stringstream ss;
ss << val;
/*access the newly-created string with str()*/
return ss.str();

Upvotes: 3

Related Questions