LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-04-2009, 02:16 AM   #1
gopalpathak2
LQ Newbie
 
Registered: Aug 2009
Posts: 1

Rep: Reputation: 0
numerical error in C program


if a=1946.498046875 & b=0.00003814697265625
then z=a-b=1946.498046875 why? i.e. in my C program it do not give correct results
 
Old 08-04-2009, 03:19 AM   #2
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Wheezy (Fluxbox WM)
Posts: 1,363
Blog Entries: 52

Rep: Reputation: 353Reputation: 353Reputation: 353Reputation: 353
Floating point numbers can only be represented with a certain amount of precision.

In C, you would normally use the 'double' type for floating point numbers, which has more precision than the 'float' type. This will improve the result in your example. (use "%lf" when formatting the output in printf [ignore this formatting, see below, %lf is only for scanf]).

Last edited by neonsignal; 08-04-2009 at 10:27 PM.
 
Old 08-04-2009, 08:15 AM   #3
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
Moved: This thread is more suitable in <Programming> and has been moved accordingly to help your thread/question get the exposure it deserves.
 
Old 08-04-2009, 12:42 PM   #4
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: Debian lenny, Slackware 12
Posts: 808

Rep: Reputation: 178Reputation: 178
Quote:
Originally Posted by neonsignal View Post
Floating point numbers can only be represented with a certain amount of precision.

In C, you would normally use the 'double' type for floating point numbers, which has more precision than the 'float' type.
Yes, this fixes the problem.
Quote:
Originally Posted by neonsignal View Post
(use "%lf" when formatting the output in printf).
The man page does not assign any meaning to %lf. %f is already adequate for variables of type double. To demonstrate, you'll get this output:
Code:
fz is 1946.49804687500000000000000000000000000
dz is 1946.49808502197265625000000000000000000
if you run this bash script:
Code:
#!/bin/sh
cat > 1.c <<EOD; gcc -Wall 1.c -o 1; ./1
#include <stdio.h>
int main(void)
{
  float  fa, fb, fz;
  double da, db, dz;

  fa=1946.498046875; fb=0.00003814697265625; fz=fa+fb;
  da=1946.498046875; db=0.00003814697265625; dz=da+db;

  printf("fz is %40.35f\n",fz);
  printf("dz is %40.35f\n",dz);

  return 0;

} /* main() */
EOD
If you need even greater precision, use variables of type long double. Constants should be followed by the letter "L", either upper or lower case. (I recommend you use upper case "L", because lower case "l" looks too much like the numeral 1.) The format is "Lf" (upper case; lower doesn't work).
 
Old 08-04-2009, 01:32 PM   #5
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,083

Rep: Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110
Quote:
Originally Posted by wje_lq View Post
If you need even greater precision, use variables of type long double.
IIUC, most architectures including x86_64 don't have long double support any more precision than double.

If you want more precision than double, use the GNU Multiple Precision library:
http://gmplib.org/
 
Old 08-04-2009, 04:22 PM   #6
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 453Reputation: 453Reputation: 453Reputation: 453Reputation: 453
Quote:
Originally Posted by gopalpathak2 View Post
if a=1946.498046875 & b=0.00003814697265625
then z=a-b=1946.498046875 why? i.e. in my C program it do not give correct results
Start from here: http://en.wikipedia.org/wiki/Floating_point and rethink the whole issue of (non)periodic fractions WRT radix.
 
Old 08-04-2009, 10:24 PM   #7
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Wheezy (Fluxbox WM)
Posts: 1,363
Blog Entries: 52

Rep: Reputation: 353Reputation: 353Reputation: 353Reputation: 353
Quote:
most architectures including x86_64 don't have long double support any more precision than double
The 8087 architecture supports an 80 bit float, which is used for 'long double' by the better compilers.
 
Old 08-05-2009, 06:54 AM   #8
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,083

Rep: Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110
Quote:
Originally Posted by neonsignal View Post
The 8087 architecture supports an 80 bit float, which is used for 'long double' by the better compilers.
Do you know a command line switch or other method to make gcc for x86_64 use the 8087 for 80 bit long double?

If I understood the documentation right, there is no way to get the Intel compiler (that I normally use) to use the 8087 in x86_64 code.

I also failed (but after not trying very hard) to get long doubles to have more precision than doubles using the Microsoft C++ compiler in x86_64 architecture.

Maybe none of those are the "better" compilers.

IIRC, most 32 bit x86 compilers support true 80 bit long doubles. 32 bit x86 may be the most popular architecture, but it isn't what I meant by most architectures.
 
Old 08-05-2009, 08:36 AM   #9
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Wheezy (Fluxbox WM)
Posts: 1,363
Blog Entries: 52

Rep: Reputation: 353Reputation: 353Reputation: 353Reputation: 353
Quote:
Do you know a command line switch or other method to make gcc for x86_64 use the 8087 for 80 bit long double?
Not sure that it is possible (or at least, practical), because some of the 64 bit instructions share state with the 8087 stack.

For the Itanium architecture, there are facilities for doing higher precision multiply and accumulate (which would be useful eg for signal processing apps). But you'd have to resort to assembler for that in most compilers. The HP-UX compiler provides an extended floating point type for this purpose (which uses the 82 bit precision in the hardware). There has been discussion about how this might be done in gcc.

As you suggest, perhaps the GMP (or the APREC) libraries are the option for most applications that need higher precision.

Last edited by neonsignal; 08-05-2009 at 08:38 AM.
 
Old 08-05-2009, 05:06 PM   #10
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 453Reputation: 453Reputation: 453Reputation: 453Reputation: 453
Quote:
Originally Posted by neonsignal View Post
Not sure that it is possible (or at least, practical), because some of the 64 bit instructions share state with the 8087 stack.

For the Itanium architecture, there are facilities for doing higher precision multiply and accumulate (which would be useful eg for signal processing apps). But you'd have to resort to assembler for that in most compilers. The HP-UX compiler provides an extended floating point type for this purpose (which uses the 82 bit precision in the hardware). There has been discussion about how this might be done in gcc.

As you suggest, perhaps the GMP (or the APREC) libraries are the option for most applications that need higher precision.
It is not possible - hardware (x86_64) doesn't support it.
 
  


Reply

Tags
error, program


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Sorting by numerical order shoemoodoshaloo Linux - Newbie 3 07-21-2009 03:52 PM
meaning of numerical error happy78 Linux - General 1 02-17-2006 04:48 PM
what is the Scalable numerical algorithms ztdep Linux - Software 1 01-15-2006 01:32 AM
Numerical keypad Craqon Linux - General 2 12-15-2004 12:42 AM
Numerical recipes in C++ marios_auth Programming 0 07-08-2004 02:19 AM


All times are GMT -5. The time now is 05:08 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration