473,324 Members | 2,248 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

Integer part of double

Ho to get valid value of integer part of double _as int value_?

Here is a program that demonstrate the problem.

------ foo.c ------
#include <stdio.h>
#include <math.h>

int main ()
{
double d1 = 0.0;
double d1i = 0.0;
double d1f = 0.0;
int i1 = 0;
int i2 = 0;
size_t k = 0;

for (k = 0; k < 1000; k++)
{
d1 = d1 + 1.1;
i1 = (int) d1;

d1f = modf (d1, & d1i);
i2 = (int) d1i;

if ( ((d1 - i1) 0.95) || ((d1i - i2) 0.95) )
{
printf ("i1 = %3d, i2 = %3d, d1 = %10f, d1 = %16.12f, d1i =
%10f%\n", i1, i2, d1, d1, d1i);
}

}
return 0;
}
-------------------
------ Run ------
i1 = 10, i2 = 10, d1 = 11.000000, d1 = 11.000000000000, d1i =
10.000000
i1 = 76, i2 = 76, d1 = 77.000000, d1 = 77.000000000000, d1i =
76.000000
i1 = 87, i2 = 87, d1 = 88.000000, d1 = 88.000000000000, d1i =
87.000000
i1 = 98, i2 = 98, d1 = 99.000000, d1 = 99.000000000000, d1i =
98.000000
i1 = 109, i2 = 109, d1 = 110.000000, d1 = 110.000000000000, d1i =
109.000000
i1 = 120, i2 = 120, d1 = 121.000000, d1 = 121.000000000000, d1i =
120.000000
i1 = 131, i2 = 131, d1 = 132.000000, d1 = 132.000000000000, d1i =
131.000000
i1 = 142, i2 = 142, d1 = 143.000000, d1 = 143.000000000000, d1i =
142.000000
i1 = 153, i2 = 153, d1 = 154.000000, d1 = 154.000000000000, d1i =
153.000000
i1 = 164, i2 = 164, d1 = 165.000000, d1 = 165.000000000000, d1i =
164.000000
i1 = 175, i2 = 175, d1 = 176.000000, d1 = 175.999999999999, d1i =
175.000000
i1 = 186, i2 = 186, d1 = 187.000000, d1 = 186.999999999999, d1i =
186.000000
i1 = 197, i2 = 197, d1 = 198.000000, d1 = 197.999999999999, d1i =
197.000000
i1 = 208, i2 = 208, d1 = 209.000000, d1 = 208.999999999999, d1i =
208.000000
i1 = 219, i2 = 219, d1 = 220.000000, d1 = 219.999999999999, d1i =
219.000000
i1 = 230, i2 = 230, d1 = 231.000000, d1 = 230.999999999999, d1i =
230.000000
i1 = 241, i2 = 241, d1 = 242.000000, d1 = 241.999999999999, d1i =
241.000000
i1 = 252, i2 = 252, d1 = 253.000000, d1 = 252.999999999999, d1i =
252.000000
i1 = 263, i2 = 263, d1 = 264.000000, d1 = 263.999999999999, d1i =
263.000000
i1 = 274, i2 = 274, d1 = 275.000000, d1 = 274.999999999999, d1i =
274.000000
i1 = 285, i2 = 285, d1 = 286.000000, d1 = 286.000000000000, d1i =
285.000000
i1 = 296, i2 = 296, d1 = 297.000000, d1 = 297.000000000000, d1i =
296.000000
-----------------
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jan 16 '07 #1
18 24531
Alex Vinokur wrote:
Ho to get valid value of integer part of double _as int value_?
If the value is positive then floor() seems a natural solution.
If the value is negative then ceil() seems a natural solution.

Keep in mind that on most machines an integer is not large enough to
hold all possible floor()/ceil() values from a double. Don't forget
that 1e222 is a very large integer.

If you insist on storing the value in an integral type, then I would at
least use a long long unless you know for sure that you will never need
more than 10 digits.

Maybe something like this:

#include <limits.h>
#include <math.h>
int intpart(double input, double *dint, long long *lint)
{
if (input 0)
*dint = floor(input);
else
*dint = ceil(input);

if (*dint < LLONG_MAX) {
*lint = (long long) *dint;
return 1;
} else {
lint = 0;
return 0;
}
}

Jan 16 '07 #2
Alex Vinokur said:
Ho to get valid value of integer part of double _as int value_?
int m = d;

If it doesn't fit, you've got problems.

long int n = d;

might solve those problems, but of course it might not.

If you just want to suppress decimals in your output, you don't have to do
any conversion - you can simply printf("%.0f\n", d);

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 16 '07 #3
Richard Heathfield wrote:
Alex Vinokur said:
Ho to get valid value of integer part of double _as int value_?

int m = d;

If it doesn't fit, you've got problems.

long int n = d;

might solve those problems, but of course it might not.

If you just want to suppress decimals in your output, you don't have to do
any conversion - you can simply printf("%.0f\n", d);
Of course, that rounds, rather than truncates.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 16 '07 #4
user923005 said:
Richard Heathfield wrote:
>Alex Vinokur said:
Ho to get valid value of integer part of double _as int value_?

int m = d;

If it doesn't fit, you've got problems.

long int n = d;

might solve those problems, but of course it might not.

If you just want to suppress decimals in your output, you don't have to
do any conversion - you can simply printf("%.0f\n", d);

Of course, that rounds, rather than truncates.
Oh, good spot. In which case, we're back to your suggestion of floor() and
ceil(), I suppose - but I *think* he's primarily interested in suppressing
trailing 0s in his output (admittedly I'm just guessing), so floor() and
ceil() wouldn't be enough on their own.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 16 '07 #5
Richard Heathfield wrote:
[snip]
>I *think* he's primarily interested in suppressing
trailing 0s in his output (admittedly I'm just guessing), so floor() and
ceil() wouldn't be enough on their own.
[snip]

I am interested in the following:

double d;
int i;

d = 15.3; // after some calculation
i = (int) d; // i == 15; It is what I want to get

d = 15.0; // after some calculation
i = (int) d; // sometimes i == 15, sometimes i == 14; I want always
to get i == 15
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jan 16 '07 #6
Alex Vinokur said:
Richard Heathfield wrote:
[snip]
>>I *think* he's primarily interested in suppressing
trailing 0s in his output (admittedly I'm just guessing), so floor() and
ceil() wouldn't be enough on their own.
[snip]

I am interested in the following:

double d;
int i;

d = 15.3; // after some calculation
i = (int) d; // i == 15; It is what I want to get
You don't need the cast.

i = d; is sufficient.
d = 15.0; // after some calculation
i = (int) d; // sometimes i == 15, sometimes i == 14; I want always
to get i == 15
Floating-point math is inherently imprecise (because computers aren't
terribly good at fitting infinity into N bits, for finite values of N). So
you'll probably find that d is actually 14.99999something. The fix is to
add a tiny number to it, big enough to nudge it over the wire if it's just
below, but not so big as to nudge it over the /next/ wire if it's actually
some way above.

So, for example, i = d + 0.001; may be acceptable to you. Or i = d +
DBL_EPSILON; - it all really depends on what you consider to be "darn it,
this is 15 even though the computer thinks it's below that", and what you
consider to be 14 even though the computer thinks it's above that. That is,
you have to choose a cut-off point.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 16 '07 #7
Richard Heathfield wrote:
user923005 said:
Richard Heathfield wrote:
Alex Vinokur said:

Ho to get valid value of integer part of double _as int value_?

int m = d;

If it doesn't fit, you've got problems.

long int n = d;

might solve those problems, but of course it might not.

If you just want to suppress decimals in your output, you don't have to
do any conversion - you can simply printf("%.0f\n", d);
Of course, that rounds, rather than truncates.

Oh, good spot. In which case, we're back to your suggestion of floor() and
printf("%.0f\n", d-0.5)

this may give -0 in the range 0.0-0.5, and to truncate towards zero one
needs to do

if (d < 0.0) {
printf("%.0f\n", d+0.5)
else {
printf("%.0f\n", d-0.5)
}

Stijn

--
S

Jan 16 '07 #8
Alex Vinokur wrote:
Richard Heathfield wrote:
[snip]
>I *think* he's primarily interested in suppressing
trailing 0s in his output (admittedly I'm just guessing), so floor() and
ceil() wouldn't be enough on their own.
[snip]

I am interested in the following:

double d;
int i;

d = 15.3; // after some calculation
i = (int) d; // i == 15; It is what I want to get

d = 15.0; // after some calculation
i = (int) d; // sometimes i == 15, sometimes i == 14; I want always
to get i == 15
In the second case, "some calculation" probably arrives
at a value that is very close to 15, but not precisely equal
to it -- you get 15.00000011432, perhaps. Converting this
to an integer chops off the fractional part, producing 15.

But what if the calculated result is just a tiny bit
small, like 14.99999987856? Converting this to int again
chops the fraction, but this time you get 14. What you
probably need to do is not to truncate the number by
converting directly to integer, but to round it first
and then convert.

If you have a C99 implementation, this is easy:

#include <math.h>
...
i = round(d);

The round() function is not part of the C90 Standard,
so you might need to do it by hand (but check the documentation;
by now, some "C90 implementations" are actually "C90 plus some
C99 goodies" if you invoke them suitably). Here's a crude but
reasonably effective way:

i = (d >= 0) ? d + 0.5 : d - 0.5;

--
Eric Sosman
es*****@acm-dot-org.invalid
Jan 16 '07 #9
Alex Vinokur wrote:
>
.... snip ...
>
I am interested in the following:

double d;
int i;

d = 15.3; // after some calculation
i = (int) d; // i == 15; It is what I want to get

d = 15.0; // after some calculation
i = (int) d; // sometimes i == 15, sometimes i == 14; I want
always to get i == 15
i = d + 0.5; /* no casts needed - they are usually errors */

--
"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
Jan 16 '07 #10

Alex Vinokur wrote:
Richard Heathfield wrote:
[snip]
I *think* he's primarily interested in suppressing
trailing 0s in his output (admittedly I'm just guessing), so floor() and
ceil() wouldn't be enough on their own.
[snip]

I am interested in the following:

double d;
int i;

d = 15.3; // after some calculation
i = (int) d; // i == 15; It is what I want to get

d = 15.0; // after some calculation
i = (int) d; // sometimes i == 15, sometimes i == 14; I want always
to get i == 15
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn
Why not just use the modf routine?

double d, x, y;

d = 15.3;
x = modf(d, &y);

x will then have 15 only and y will have whatever the 3 represents
(whether it is actually 3 or .298). You can then print them out as
doubles or whatever representation you like.

Jan 16 '07 #11

soccertl wrote:
Alex Vinokur wrote:
Richard Heathfield wrote:
[snip]
>I *think* he's primarily interested in suppressing
trailing 0s in his output (admittedly I'm just guessing), so floor() and
ceil() wouldn't be enough on their own.
[snip]

I am interested in the following:

double d;
int i;

d = 15.3; // after some calculation
i = (int) d; // i == 15; It is what I want to get

d = 15.0; // after some calculation
i = (int) d; // sometimes i == 15, sometimes i == 14; I want always
to get i == 15
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Why not just use the modf routine?

double d, x, y;

d = 15.3;
x = modf(d, &y);

x will then have 15 only and y will have whatever the 3 represents
(whether it is actually 3 or .298). You can then print them out as
doubles or whatever representation you like.
By the way, you could then test "y" to see if it is >= .5 and if it is
then add 1 to "x".

Jan 16 '07 #12
"Alex Vinokur" <al****@users.sourceforge.netwrites:
Richard Heathfield wrote:
[snip]
>>I *think* he's primarily interested in suppressing
trailing 0s in his output (admittedly I'm just guessing), so floor() and
ceil() wouldn't be enough on their own.
[snip]

I am interested in the following:

double d;
int i;

d = 15.3; // after some calculation
i = (int) d; // i == 15; It is what I want to get

d = 15.0; // after some calculation
i = (int) d; // sometimes i == 15, sometimes i == 14; I want always
to get i == 15
What result do you want if d == 15.9? 15.7? 15.5?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 16 '07 #13
CBFalconer wrote:
[snip]
i = d + 0.5; /* no casts needed - they are usually errors */
Suppose that d contains -14.42
i now contains -13

Jan 17 '07 #14

Keith Thompson wrote:
[snip]
What result do you want if d == 15.9? 15.7? 15.5?
Also 15.

[snip]

Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jan 17 '07 #15
user923005 wrote:
CBFalconer wrote:
[snip]
i = d + 0.5; /* no casts needed - they are usually errors */

Suppose that d contains -14.42
i now contains -13
If you are worrying about -ve values, do as someone else suggested
and use:

i = d + (d < 0) ? -0.5 : 0.5;

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 17 '07 #16
"Alex Vinokur" <al****@users.sourceforge.netwrites:
Keith Thompson wrote:
[snip]
What result do you want if d == 15.9? 15.7? 15.5?

Also 15.

[snip]
Based on that, you want either trunc() or floor(), depending on how
you want to treat negative numbers.

But earlier, you said (or at least implied) that you want 15.9999+ to
map to 16. You need to decide how close to an integer the number
needs to be before you round it up rather than down.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 17 '07 #17
Keith Thompson wrote:
"Alex Vinokur" <al****@users.sourceforge.netwrites:
Keith Thompson wrote:
[snip]
What result do you want if d == 15.9? 15.7? 15.5?
Also 15.

[snip]

Based on that, you want either trunc() or floor(), depending on how
you want to treat negative numbers.
trunc() is not ANSI C; floor() doesn't solve the problem.

[snip]

Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jan 17 '07 #18
"Alex Vinokur" <al****@users.sourceforge.netwrites:
Keith Thompson wrote:
"Alex Vinokur" <al****@users.sourceforge.netwrites:
Keith Thompson wrote:
[snip]
What result do you want if d == 15.9? 15.7? 15.5?
>
Also 15.
>
[snip]
Based on that, you want either trunc() or floor(), depending on how
you want to treat negative numbers.

trunc() is not ANSI C; floor() doesn't solve the problem.
trunc() is C99; it should be easy enough to re-implement it in C90.

(Historical note: ANSI introduced the first C standard in 1989. ISO
adopted it, with editorial changes, in 1990; ANSI then adopted the ISO
C90 standard. ISO introduced the new C99 standard in 1999; this was
also adopted by ANSI. So strictly speaking, C99 is ANSI C, though the
term is often applied to the (formally obsolete) C89/C90 standard.)

floor() does map 15.9, 15.7, and 15.5 to 15. If that doesn't solve
your problem, you need to define your problem more precisely, perhaps
by addressing the portions of my article that you snipped.

Upthread, you wrote:

| d = 15.0; // after some calculation
| i = (int) d; // sometimes i == 15, sometimes i == 14; I want always
| to get i == 15

Obviously d isn't really equal to 15.0; it's 14.999something.

So 15.9 maps to 16, but 15.9999..., for enough 9s, maps to 16. You
need to decide exactly where the result changes.

And you need to decide what to do with negative numbers.

Precisely defining the problem is a large part of solving it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 17 '07 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Michael Søndergaard | last post by:
I Pascal there are a function for retriving the fractional part of a real number (Frac), I can't find any in the dotnet framework. The function needs to remove the integer part and keep only the...
4
by: rz0 | last post by:
Hi all, This is a question about both C89 and C99 and is based on my partial reading of the standard drafts (one from before C89 but mainly N1124). If appropriate, please give a...
7
by: Joe | last post by:
Hello All: Does anyone know the difference between CType(x,Integer) vs. Integer.Parse(x)? Is there a performance advantage to one or the other? TIA, -- Joe
33
by: gk245 | last post by:
I mean, anything that follows a 0 is automatically turned into a octal number. I want to have a integer variable that will hold numbers as integers even if they begin with a zero. for example:...
8
by: gk245 | last post by:
This is part of a bigger program, but i made it simple (basically the OT_hours function is supposed to determine if the number entered is over 40 hours or not and return the appropriate answer): ...
7
by: laura | last post by:
Hi, I have a variable of type double. I need to know if there is an integer number store there. How can I test that ? I also have a default precision for doing this operation. Many thanks,...
17
by: Ivan K. | last post by:
I am looking at some legacy code, which begins by allocating a double matrix with the dmatrix() function from NRC as follows: double **A, **augin, **augout, **aa; A = dmatrix(1,...
12
by: aaragon | last post by:
I have this scenario: several arrays for which I have their fixed values at compilation time. Now, at runtime I need to access a specific array depending on an integer but I want to avoid if and...
88
by: santosh | last post by:
Hello all, In K&R2 one exercise asks the reader to compute and print the limits for the basic integer types. This is trivial for unsigned types. But is it possible for signed types without...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.