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 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;
}
}
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.
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.
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.
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
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.
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
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
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>
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.
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".
"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.
CBFalconer wrote:
[snip]
i = d + 0.5; /* no casts needed - they are usually errors */
Suppose that d contains -14.42
i now contains -13
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>
"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.
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
"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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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
|
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:...
|
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):
...
|
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,...
|
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,...
|
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...
|
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...
|
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...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
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...
|
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...
|
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...
|
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...
|
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....
|
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
|
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...
| |