473,408 Members | 2,417 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,408 software developers and data experts.

testing whether a double is a whole number

The program calculates the continued fraction representation of the input:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
double diff, n, r, i;

if(argc != 2) exit(EXIT_FAILURE);

n = strtod(argv[1], NULL);

printf("\n [");

while(1)
{
i = (int)n;
printf(" %.f", i);
diff = n - i;
r = 1 / diff;
if(r is a whole number) /* ??? */
{
printf(" %.f", r);
break;
}
n = r;
}

printf("]\n");

return 0;
}

In the while() loop, I want to test whether r is a whole number. If it
is, it is the last denominator of the continued fraction and I'm done.
Incredibly, I was not able to do this in any straighforward way. For
example, if(r == (int)r) didn't work. I finally kludged it by writing a
function that counts the significant decimal digits in a real number,
but there has got to be a better way. How would you solve the problem?

(And, yes, I realize that if the input is irrational the program doesn't
terminate.)

David
Nov 15 '05 #1
3 9884
In article <xNGxe.148629$El.135738@pd7tw1no>,
David Marsh <dm****@mail.com> wrote:
The program calculates the continued fraction representation of the input: r = 1 / diff;
if(r is a whole number) /* ??? */ In the while() loop, I want to test whether r is a whole number. If it
is, it is the last denominator of the continued fraction and I'm done.
Incredibly, I was not able to do this in any straighforward way. For
example, if(r == (int)r) didn't work. I finally kludged it by writing a
function that counts the significant decimal digits in a real number,
but there has got to be a better way. How would you solve the problem?
You don't. Your entire sequence is subject to increasing round-off
error. Even if r -appeared- to be a whole number, you wouldn't
be able to tell whether you had calculated the exact continued
fraction, or had instead merely ended up rounding off to that
value.

The algorithm you are using to calculate the continued fraction
only works when there is indefinite precision.

Consider, for example, something as simple as the input
value (double) 1.0 / (double) 3.0 . No matter how many bits
of precision you have, if you are using a binary representation
then you have the binary repeating fraction 01 (i.e.,
1/3 is binary 0.0101010101...) That is [using fraction notation]
1/4 + 1/16 + 1/64 + 1/256 + 1/1024 + 1/4096 + ...
and after 2N mantisa bits, your value is different from 1/3 by
the value 1/(3 * 2**(2N)).

If you expand this logic, then because of limited precision
on input, then even if you didn't lose precision during
the calculation, only the fractions which are sums of
negative powers of 2 are going to come out properly,
and *every* fraction that involves a prime greater than 2
would merely come out expressed in terms of negative
powers of 2, to the limit of the number of mantisa bits.
So... you cannot do any meaningful accurate continued-fraction
calculation with the algorithm you give.

The closest you can get is to lose a bit of precision,
understand that wrong answers will be given sometimes,
and change the "if" to check to see whether r is within
a tolerance of a whole number. For example,
if(r is a whole number) /* ??? */


would become something like

if ( abs(r - trunc(r)) < delta )

and you get to choose the delta according to how much slop you
are willing to put up with.
--
"This was a Golden Age, a time of high adventure, rich living and
hard dying... but nobody thought so." -- Alfred Bester, TSMD
Nov 15 '05 #2
David Marsh wrote:
The program calculates the continued fraction representation of the input: In the while() loop, I want to test whether r is a whole number. If it
is, it is the last denominator of the continued fraction and I'm done.
Incredibly, I was not able to do this in any straighforward way. For
example, if(r == (int)r) didn't work. I finally kludged it by writing a
function that counts the significant decimal digits in a real number,
but there has got to be a better way. How would you solve the problem?


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>

#define ALMOST_ZERO (1.e-10)
#define MAXV 20
int main(int argc, char *argv[])
{
double thenumber, copy;
double denominator[MAXV], n, d, t;
int pass;

if (argc != 2) {
fprintf(stderr, "usage: %s number\n", argv[0]);
exit(EXIT_FAILURE);
}
thenumber = strtod(argv[1], 0);
if (thenumber < 0) {
printf("changing sign of %.f\n", thenumber);
thenumber *= -1;
}
printf("[ ");
for (copy = thenumber, pass = 0; pass < 20; pass++) {
copy = modf(copy, &denominator[pass]);
printf("%.f ", denominator[pass]);
if (copy < ALMOST_ZERO)
break;
copy = 1. / copy;
}
printf("]\n");
if (pass == 20)
pass--;
if (pass == 0) {
n = denominator[0];
d = 1;
}
else {
for (n = 1, d = denominator[pass], pass--; pass > 0; pass--) {
t = d * denominator[pass] + n;
n = d;
d = t;
}
n += d * denominator[0];
}
printf("%.f/%.f = %.*g\n"
" the original number was %.*g\n", n, d, DBL_DIG,
n / d, DBL_DIG, thenumber);

return 0;
}

Nov 15 '05 #3
Walter Roberson wrote:
You don't. Your entire sequence is subject to increasing round-off
error. Even if r -appeared- to be a whole number, you wouldn't
be able to tell whether you had calculated the exact continued
fraction, or had instead merely ended up rounding off to that
value.

The algorithm you are using to calculate the continued fraction
only works when there is indefinite precision.
So... you cannot do any meaningful accurate continued-fraction
calculation with the algorithm you give.

The closest you can get is to lose a bit of precision,
understand that wrong answers will be given sometimes,
and change the "if" to check to see whether r is within
a tolerance of a whole number. For example,


OK, I think I understand the precision issue. The source of the
algorithm (and everything I know about continued fractions) is:
http://en.wikipedia.org/wiki/Continued_fraction (Calculating continued
fraction representations).

Martin Ambuhl's program uses the fudge factor approach. I compared the
output of his program with mine. In every case my output was comparable
to his. Some examples below:

input David's program Martin's program
---------------------------------------------

..3 0;3,3 0;3,2,1
..5 0;2 0;2
..75 0;1,3 0;1,3
..829 0;1,4,1,5,1,1,2,1,3 0;1,4,1,5,1,1,2,1,3
..999 0;1,999 0;1,998,1

Anyway, it has become a discussion of algorithms and CS, not standard C,
so it's off-topic here. Thanks for your comments. BTW, are you Canadian?

David

Nov 15 '05 #4

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

Similar topics

4
by: Edvard Majakari | last post by:
Hi, I just found py.test and converted a large unit test module to py.test format (which is actually almost-no-format-at-all, but I won't get there now). Having 348 test cases in the module and...
0
by: Billy Patton | last post by:
I have worked out a testing procedure that works well for me. Here it is for your taking. It has evolved over 15 years of c and perl coding and testing. My perl version looks VERY similar. It...
9
by: Sisyphus | last post by:
Hi, I have some software that does the following (in an attempt to determine whether the double x, can be represented just as accurately by a float): void test_it(double x) { float y = x;...
72
by: Jacob | last post by:
I have compiled a set og unit testing recommendations based on my own experience on the concept. Feedback and suggestions for improvements are appreciated: ...
27
by: brad | last post by:
Does anyone else feel that unittesting is too much work? Not in general, just the official unittest module for small to medium sized projects? It seems easier to write some quick methods that are...
2
by: yogi_bear_79 | last post by:
I have a double of unknown length that I need to split at the decimal. I thought I would convert it either to a string or a char. char seems to be the best since it easily lends itself to...
24
by: David | last post by:
Hi list. What strategies do you use to ensure correctness of new code? Specifically, if you've just written 100 new lines of Python code, then: 1) How do you test the new code? 2) How do...
11
by: VK | last post by:
In the continuation of the discussion at "Making Site Opaque -- This Strategy Feasible?" and my comment at http://groups.google.com/group/comp.lang.javascript/msg/b515a4408680e8e2 I have...
98
by: scienceman88 | last post by:
I'm making a prime finder another thing I'd like is a loop to check all possible odd factors if I can do that i can find all primes under 18 quintillion I think and store them in files ( yes I have...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...

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.