Archived

This topic is now archived and is closed to further replies.

Is there some way I can get the value of the non integral portion of a double

This topic is 4942 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Sry, c++, and i need the value isolated into an int. not a double. all ive come up with is

while(int(Number+.99999999999)>int(Number))
{
Number*=10;
}




this isnt working how i need it to for some reason, does using int() as i do up there permanently change the value of number or is it just modified for the comparison?

[edited by - unliterate on May 30, 2004 10:07:54 PM]

Share this post


Link to post
Share on other sites
Well i just debugged and that portion of my code works as it should, so the problem must lie else where.

EDIT: after more debugging i relised there is a problem. it seems very inconsistant, sometimes this produces the desired result and sometimes it doesnt for diferent values of Number. (sometimes the output will looke like 1.2e^16 for Number=1.2;


//test

int main()
{
double Number=233.1234;

while(long(Number+.99999)>long(Number))
{
Number*=10;
}

cout<<Number;
cin>>Number;
return 0;
}



[edited by - unliterate on May 30, 2004 10:16:32 PM]

[edited by - unliterate on May 30, 2004 10:17:56 PM]

Share this post


Link to post
Share on other sites
Sort of off the top of my head, but you could convert the number into a string, shorten the string to consist only of the "non-integral part", then convert that string back to an integer. This is probably the least-efficient method

Share this post


Link to post
Share on other sites
quote:
Original post by 3DNeophyte
Sort of off the top of my head, but you could convert the number into a string, shorten the string to consist only of the "non-integral part", then convert that string back to an integer. This is probably the least-efficient method


If you ABSOLUTELY NEED to do something like this, I''d probably go with this. It might not be the fastest way but at least its clean in its own sort of perverted way

Share this post


Link to post
Share on other sites
'Sorry we don't know what you are talking about.

You say you need the nonintegral portion of a double to be "isolated into" an int. That doesn't even make sense.
'

it sure makes sence to me.. the problem is its not consistant with any code im showing so ill redescribe what i need.

given
double 12.34
i want
int 1234

[edited by - unliterate on May 30, 2004 10:21:11 PM]

Share this post


Link to post
Share on other sites
You absolutely can do this with an array of characters. Anything that can be done to a string can be done through a character array, since both are equivalent - just remember the null character when you''re getting ''dirty'' with these

Share this post


Link to post
Share on other sites
The problem is ill-defined because the way floating point numbers are represented is an approximation usually. The character string method is probably the closest to what you want. e.g.

char buf[LOTSAROOM];
char *s;
sprintf(buf, "%f", floatval);
s = strchr(buf, ''.'');
if(s)
{
strcpy(s, s+1);
printf("%s\n", buf);
}
else
printf("d''oh!\n");


Share this post


Link to post
Share on other sites
If you''re going my way, you shouldn''t need to alter place values. From the information that you''ve given, I''m thinking this is what you want:

double d = 13.222;

I''m guessing you want there to be an integer with the value 13222, yes? So turn d into a string (use your favorite number-to-string function in whatever language). Remove the decimal, then convert the string into an integer (using a string-to-int function -- atoi(char* ) in C/C++ ). You shouldn''t have to express any place value as an integer, for this is practically done for you by the string-to-integer function. If still confused, just ask

Share this post


Link to post
Share on other sites
Here's a numerical solution, but it's slightly marred due to floating-point precision. The function assumes you already know the number of decimal places.

int double_to_int(double param, int places)
{
int whole = (int)floor(param);
double new_d = param - whole;

int mult = 10;

for (int i = 1; i < places; i++)
mult *= 10;

int int_d = (int)(new_d * mult);
whole *= mult;

return (whole + int_d);
}

Please excuse the horrible variable names

3.14 and 12345.6789 worked just fine. 3.13 gave 312 for some reason (I'm guessing floating-point errors, but I don't know much in this category). Anyway, it's a start in case you're reaching for a numerical approach. I'd just go with the string solution :D

Edit: You could try to expand this function to accept an unknown number of decimal places, using a concrete maximum as a limit. The algorithm would be to multiply by 10 and compare the result to the floor of the double multiplied by 10 - if they're equal, then you have the number of places and you can continue on to the last part. If not, then multiply by 100, 10^3, 10^4, and so on until you hit your places-limit. The problem here is actually comparing the two floating-point values - I couldn't resolve this issue, but if you can get it to work then you'll be well on your way

[edited by - 3DNeophyte on May 30, 2004 11:40:31 PM]

Share this post


Link to post
Share on other sites
I''m currently learning IA-32 asm, so this was a real exercize for me. It may need some tweaking, but may also be the fastest solution on the intarweb (j/k): (took me 1/2 hour of thinking/finding instructions)


double ShiftLeft15D = 4503599627370496.0f;
//2^52 (size of fpart of double precision fp)

//and approximately 10^15 in decimal,hence the name.


int DoubleToIntegral32WithFrac(double value)
{
int IntegerPart;
int FracPart;
_asm {
FLD value
FLD ST(0)
FRNDINT
FSUB ST(1), ST(0)
FISTP IntegerPart
FABS
FMUL ShiftLeft15D
FISTP FracPart
MOV EAX, FracPart
BSF ECX, EAX
JNZ DestDefined
MOV CL, 0
DestDefined: SHR EAX, CL
BSR ECX, EAX
JZ DestUndefined
INC CL
JMP DestDefined2
DestUndefined: MOV CL, 0
DestDefined2: MOV EDX, IntegerPart
SAL EDX, CL
OR EAX, EDX
MOV IntegerPart, EAX
}
return IntegerPart;
}

It would be interesting to see whether that works or not, lol Nvm, this is probably the slowest code.





Share this post


Link to post
Share on other sites