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

having problems with math library

I wrote a function that should test if a given number is a palindrom,
but when I ran it in a little testprogram it behaves strange.

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

#define MAXSIZE 100000000

int is_palindrom(double n) {
double m = 0;
double x;
double y;
double i;
for(i = 10; i <= MAXSIZE; i *= 10) {
x = modf(n/i, &y);
printf("x = modf(%lf, &y)\n\tx == %lf, y == %lf\n", n/i, x, y);
modf((x*10), &y);
printf("modf(%lf, &y)\n\ty == %lf\n", x*10, y);
m += y;
printf("is_palindrom: m currently is %lf\n", m);
m *= 10;
}
while(modf((m/10), &x) == 0)
m /= 10;
printf("is_palindrom: m finally is %lf\n", m);
return n == m;
}

void print_wether_pal(double n) {
printf("\ntesting wheter %lf is a palindrom...\n", n);
printf("\t%lf %s a palindrom\n", n, is_palindrom(n) ? "is" :
"isn't");
}

int main(int argc, char *argv[]) {
print_wether_pal(666);
print_wether_pal(404);
print_wether_pal(3);
print_wether_pal(40);
print_wether_pal(99999999);
return 0;
}

Every first time the second modf in the for-loop in is_palindrom is
called, it returns a number too small by one. This is a snippet of the
program's output:

testing wheter 666.000000 is a palindrom...
x = modf(66.600000, &y)
x == 0.600000, y == 66.000000
modf(6.000000, &y)
y == 5.000000 <<< should be 6
is_palindrom: m currently is 5.000000
x = modf(6.660000, &y)
x == 0.660000, y == 6.000000
modf(6.600000, &y)
y == 6.000000 <<< now is 6!

I know that this isn't really a bug and that the problem results lies
in the internal representation of floating point numbers in the
computer, but is there a way to overcome that problem?
Nov 14 '05 #1
6 1625

"damian birchler" <da*************@bluewin.ch> wrote in message
news:29**************************@posting.google.c om...
I wrote a function that should test if a given number is a palindrom,
but when I ran it in a little testprogram it behaves strange.

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

#define MAXSIZE 100000000

int is_palindrom(double n) {
double m = 0;
double x;
double y;
double i;
for(i = 10; i <= MAXSIZE; i *= 10) {
x = modf(n/i, &y);
printf("x = modf(%lf, &y)\n\tx == %lf, y == %lf\n", n/i, x, y);
modf((x*10), &y);
printf("modf(%lf, &y)\n\ty == %lf\n", x*10, y);
m += y;
printf("is_palindrom: m currently is %lf\n", m);
m *= 10;
}
while(modf((m/10), &x) == 0)
m /= 10;
printf("is_palindrom: m finally is %lf\n", m);
return n == m;
}

void print_wether_pal(double n) {
printf("\ntesting wheter %lf is a palindrom...\n", n);
printf("\t%lf %s a palindrom\n", n, is_palindrom(n) ? "is" :
"isn't");
}

int main(int argc, char *argv[]) {
print_wether_pal(666);
print_wether_pal(404);
print_wether_pal(3);
print_wether_pal(40);
print_wether_pal(99999999);
return 0;
}

Every first time the second modf in the for-loop in is_palindrom is
called, it returns a number too small by one. This is a snippet of the
program's output:

testing wheter 666.000000 is a palindrom...
x = modf(66.600000, &y)
x == 0.600000, y == 66.000000
modf(6.000000, &y)
y == 5.000000 <<< should be 6
is_palindrom: m currently is 5.000000
x = modf(6.660000, &y)
x == 0.660000, y == 6.000000
modf(6.600000, &y)
y == 6.000000 <<< now is 6!

I know that this isn't really a bug and that the problem results lies
in the internal representation of floating point numbers in the
computer, but is there a way to overcome that problem?


If I'm reading this correctly, the largest integer you're going to get
without extraordinary means is an unsigned long. Per K&R B11 , ULONG_MAX,
defined in limits.h, is in the 4 hundred millions. Usage in chp 2. MPJ
P.S. Palindrome received a terminal "e" with William the Conqueror.
Nov 14 '05 #2
da*************@bluewin.ch (damian birchler) writes:
I wrote a function that should test if a given number is a palindrom,
but when I ran it in a little testprogram it behaves strange.

[program using 'double's snipped]

I know that this isn't really a bug and that the problem results lies
in the internal representation of floating point numbers in the
computer, but is there a way to overcome that problem?


How about using 'unsigned long' rather than 'double'?
Nov 14 '05 #3
"damian birchler" <da*************@bluewin.ch> wrote in message
news:29**************************@posting.google.c om...
I wrote a function that should test if a given number is a palindrom,
but when I ran it in a little testprogram it behaves strange.

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

#define MAXSIZE 100000000

int is_palindrom(double n) {
double m = 0;
double x;
double y;
double i;
for(i = 10; i <= MAXSIZE; i *= 10) {
x = modf(n/i, &y);
printf("x = modf(%lf, &y)\n\tx == %lf, y == %lf\n", n/i, x, y);
modf((x*10), &y);
printf("modf(%lf, &y)\n\ty == %lf\n", x*10, y);
m += y;
printf("is_palindrom: m currently is %lf\n", m);
m *= 10;
}
while(modf((m/10), &x) == 0)
m /= 10;
printf("is_palindrom: m finally is %lf\n", m);
return n == m;
}

void print_wether_pal(double n) {
printf("\ntesting wheter %lf is a palindrom...\n", n);
printf("\t%lf %s a palindrom\n", n, is_palindrom(n) ? "is" :
"isn't");
}

int main(int argc, char *argv[]) {
print_wether_pal(666);
print_wether_pal(404);
print_wether_pal(3);
print_wether_pal(40);
print_wether_pal(99999999);
return 0;
}

Every first time the second modf in the for-loop in is_palindrom is
called, it returns a number too small by one. This is a snippet of the
program's output:

testing wheter 666.000000 is a palindrom...
x = modf(66.600000, &y)
x == 0.600000, y == 66.000000
modf(6.000000, &y)
y == 5.000000 <<< should be 6
is_palindrom: m currently is 5.000000
x = modf(6.660000, &y)
x == 0.660000, y == 6.000000
modf(6.600000, &y)
y == 6.000000 <<< now is 6!

I know that this isn't really a bug and that the problem results lies
in the internal representation of floating point numbers in the
computer, but is there a way to overcome that problem?


You have to be very careful with floating point precision. The following
code works for me (VC7):

int is_palindrom(double n)
{
double m = 0;
double x;
for (x = floor(fabs(n)); x > 0; x = floor(x/10))
m = m*10 + fmod(x, 10);
printf("is_palindrom: m finally is %lf\n", m);
return n == m;
}

Note that fmod() will retain precision better than modf() because the
division is managed inside the function instead of outside. The fmod()
function gives you the most accurate remainder of a division, whereas modf()
only separates the integer and fractional parts of a number (i.e. after a
division). If both parameters of fmod() are integers and can be fully
represented within the precision of IEEE doubles (53 bits = 15-16 digits)
then the fmod() result is exact. I think I got this right.

If unsigned long precision (32 bits (=9-10 digits) on 32-bit platforms) is
sufficient I would recommend using something like this instead:

int is_palindrom(unsigned long n)
{
unsigned long m = 0;
unsigned long x;
for (x = n; x > 0; x /= 10)
m = m*10 + x%10;
printf("is_palindrom: m finally is %lu\n", m);
return n == m;
}

Dag
Nov 14 '05 #4
Tim Rentsch <tx*@alumnus.caltech.edu> wrote in message news:<kf*************@alumnus.caltech.edu>...
da*************@bluewin.ch (damian birchler) writes:
I wrote a function that should test if a given number is a palindrom,
but when I ran it in a little testprogram it behaves strange.

[program using 'double's snipped]

I know that this isn't really a bug and that the problem results lies
in the internal representation of floating point numbers in the
computer, but is there a way to overcome that problem?


How about using 'unsigned long' rather than 'double'?

Originally this was exactely what I wanted to do. But because most
arguments and results to the functions in the math library are either
of type float or double I decided to declare my varibles to double so
that I don't have to cast them everytime they are used. Actually I
tried this once (using unsigned longs), but my program wouldn't
finish, it stuck as if it was in a endless loop. And there is another
problem. How would x = modf(n/i, &y) work, given n and i are unsigned
longs? Integer divisons don't result in floating point numbers. do
they?
Nov 14 '05 #5
Merrill & Michele wrote:
"damian birchler" <da*************@bluewin.ch> wrote in message
news:29**************************@posting.google.c om...
[ snip ]
If I'm reading this correctly, the largest integer you're going to get
without extraordinary means is an unsigned long. Per K&R B11 , ULONG_MAX,
defined in limits.h, is in the 4 hundred millions. Usage in chp 2. MPJ
P.S. Palindrome received a terminal "e" with William the Conqueror.


#define ULONG_MAX 4294967295UL

Surely in the 4 thousand millions.
--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #6
MPJ wrote:
If I'm reading this correctly, the largest integer you're going to get
without extraordinary means is an unsigned long. Per K&R B11 , ULONG_MAX, defined in limits.h, is in the 4 hundred millions. Usage in chp 2. MPJ
P.S. Palindrome received a terminal "e" with William the Conqueror.
"Joe Wright" wrote:
#define ULONG_MAX 4294967295UL

Surely in the 4 thousand millions.


Correct you are. I'll remember the ballpark figure by it being somewhat
smaller than Halliburton's no-bid contract. MPJ
Nov 14 '05 #7

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

Similar topics

2
by: Justin Lemkul | last post by:
Hello all, I am hoping someone out there will be able to help me. I am trying to install a program that utilizes NumPy. In installing NumPy, I realized that I was lacking Atlas. I ran into...
0
by: Richard Taylor | last post by:
User-Agent: OSXnews 2.07 Xref: number1.nntp.dca.giganews.com comp.lang.python:437315 Hi I am trying to use py2app (http://undefined.org/python/) to package a gnome-python application...
3
by: DrJRice | last post by:
I have just switched from VB6 to vb .net. In Vosual Studio.net I am missing the reference to System.Math and can not find it anywhere. I assume is is System.Math.dll. Where the hell is it? ...
6
by: Mitchell Vincent | last post by:
Just making sure I'm not missing the boat here, but are there any special routines for doing currency math (fixed precision stuff) in .NET? The wonderful problems of doing math on decimals tend...
5
by: Martin Vilcans | last post by:
Hi, I'm new to this mailing list and fairly new to Python as well. I'm working on a prototype for a 3D game using OpenGL, and take this opportunity to learn Python better. I'm looking for a good...
15
by: Chris | last post by:
>>from math import * 0.0 1.2246063538223773e-016 -2.4492127076447545e-016 1.0 -1.0 1.0 The cosine function works fine, but I'm getting weird answers for sine. Is this a bug? Am I doing...
6
by: 3than7 | last post by:
I am writing an application to solve Pythagorean Theorum Problems. This is on my own time, i am using a book to learn c++, and after doing a fahrenheit to celsuis program from that book, i wanted...
18
by: sam_cit | last post by:
Hi Everyone, int main() { printf("not included stdio.h"); } Yes, i haven't included stdio.h and my compiler would generate a warning and would assume that it would return a int, my question...
3
Atli
by: Atli | last post by:
Hi everybody. This is not so much a problem, since I have already managed to find a solution, but my solution requires the use of the eval() function, which I just hate to use. The problem is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.