Solved

Double and long double in g++

Posted on 2001-06-17
21
1,138 Views
Last Modified: 2010-08-05
The output of the following code is

%x30
                    1.111111111111111164357484e-05
%x30
                    1.111111111111111164357484e-05
%x30
                       0.0000111111112346407026052


but pil is a long double variable and I want it to be printed to higher precision than pid.

How can I do this?

How can I do this using c-style sprintf?

#include<iostream>
#include<iomanip>
#include<typeinfo>
#include<fstream>
#include<string>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<dirent.h>
#include<sys/dirent.h>
#include<fcntl.h>
#include<errno.h>
#include<paths.h>
#include<math.h>

void main(void){
  long double pil=0.000011111111111111111111111111111111111111111111111;
  double pid=pil;
  float pi=pil;

  cout.precision(50);

  string t;
  {
    cout<<"%x30"<<endl;
    char*z=new char[300];
    sprintf(z,"%50.25Lg",pil);
    t=z;
    delete[]z;
    cout<<t<<endl;
  }    
  {
    cout<<"%x30"<<endl;
    char*z=new char[300];
    sprintf(z,"%50.25g",pid);
    delete[]z;
    t=z;
    cout<<t<<endl;
  }    
  {
    cout<<"%x30"<<endl;
    char*z=new char[300];
    sprintf(z,"%50.25f",pi);
    delete[]z;
    t=z;
    cout<<t<<endl;
  }    



}

0
Comment
Question by:glebspy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 7
  • 2
  • +1
21 Comments
 
LVL 30

Expert Comment

by:Axter
ID: 6200723
Exactly what precision are you looking for?
Give an example of what you want as an output.
0
 
LVL 1

Author Comment

by:glebspy
ID: 6200732
%x30
                                 1.111111111111111111111111e-05
              %x30
                                 1.111111111111111164357484e-05
              %x30
                                    0.0000111111112346407026052
0
 
LVL 30

Expert Comment

by:Axter
ID: 6200745
int main(int argc, char* argv[])
{
     char buffer[1024];
     long double num_list[5] = {
          1.1234567890123456789012345,
          0.1234567890123456789012345,
          543.1234567890123456789012345,
          1.0000111111112346407026052,
          1.0000111111192346407026052};
     for (int d = 0;d < 5;d++)
     {
          sprintf(buffer,"%1.25e",num_list[d]);
          printf("Value of buffer = %s\n",buffer);
     }
               
     return 0;
}
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 30

Expert Comment

by:Axter
ID: 6200748
The above example code outputs the following:
Value of buffer = 1.1234567890123457000000000e+000
Value of buffer = 1.2345678901234568000000000e-001
Value of buffer = 5.4312345678901238000000000e+002
Value of buffer = 1.0000111111112346000000000e+000
Value of buffer = 1.0000111111192347000000000e+000

Is this what you're looking for?
0
 
LVL 1

Author Comment

by:glebspy
ID: 6200753
I don't think so.

The point is to compare and contrast the precision stored in a long double relative to a double, relative to a float.  

I need to be able to demonstrate that a long double holds more digits than a double. That is what I want my programme to do. As you can see, it doesn't.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6200755
To change the precision in sprintf/printf you need to add a decimal before the field type character, and then add numbers before and after the decimal.
Example:

printf("%3.4i", number);

The above example outputs a number with 3 digits to the left of the decimal, and 4 digits to the right of the decimal.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6200757
>>The point is to compare and contrast the precision
>>stored in a long double relative to a double, relative
>>to a float
This depends on your computer.  Does it use a  32bit Integer or a 64bit Integer.

What is your OS, and what compiler are you using?
0
 
LVL 1

Author Comment

by:glebspy
ID: 6200760
I don't think so.

The point is to compare and contrast the precision stored in a long double relative to a double, relative to a float.  

I need to be able to demonstrate that a long double holds more digits than a double. That is what I want my programme to do. As you can see, it doesn't.
0
 
LVL 1

Author Comment

by:glebspy
ID: 6200764
sorry, I didn't intend to repost that.

vil@vela:~>uname -a
SunOS vela 5.7 Generic_106541-08 sun4m sparc sun4m

vil@vela:~>g++ -v
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.7/2.95.1/specs
gcc version 2.95.1 19990816 (release)
0
 
LVL 30

Expert Comment

by:Axter
ID: 6200766
Do you know how many bits are in your double adn long double?
0
 
LVL 30

Expert Comment

by:Axter
ID: 6200767
Do you know how many bits are in your double AND long double?
0
 
LVL 1

Author Comment

by:glebspy
ID: 6200769
No. The expected functionality is of course that long double should have more.

I can try to find out if there's a simple way.

I'm going to lunch now, back in an hour or so.
0
 
LVL 1

Author Comment

by:glebspy
ID: 6200900
I'm back.
0
 
LVL 7

Accepted Solution

by:
KangaRoo earned 100 total points
ID: 6201069
>> a simple way
Eh, yes, check the headers that #define limits for floating point vars, in my MinGW GCC that is <float.h>. The #defines you need to see are probably DBL_DIG and DBL_EPSILON

>> The expected functionality is of course that long double should have more
Indeed, but at least with GCC on Win32 there is no difference between double and long double (both are 64 bit floating points).
0
 
LVL 1

Author Comment

by:glebspy
ID: 6201100
hmm,
 I found a float.h in /usr/bin/include, but I don't explicitly include<float.h>. (It contains as you suggest the identifiers DBL_DIG, DBL_EPS, LDBL_DIG and LDBL_EPS.)
 I tried putting
  cout<<DBL_DIG<<endl; in my executable but it gave me an error message. On the other hand it doesn't complain when I declare a long double.
 I don't understand this behaviour. If you can explain it and give me a prescription, I'd be grateful. It sounds like it would make a difference if I included float.h, but I don't understand why.
0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 6201759
why not just use sizeof?

#include <iostream>

using namespace std;

int main()
{
    cout << sizeof(double) << endl;  // 8 with VC++ on Win32
    cout << sizeof(long double) << endl; // 8 with VC++ on Win32
   
    return 0;
}
0
 
LVL 7

Expert Comment

by:KangaRoo
ID: 6201883
I only pointed you at <float.h> to take a look at those #defines, it is not required to #include this file when using floating points.

If double and long double actually have different sizes on your system, then the value #defined for DBL_DIG is different from that #defined with LDBL_DIG and it is easier to read that from the header then finding it out by actually writing the code for it.

With MinGW gcc there is no difference between double and long double, when you declare a long double the is compiled the same as when you declared a double. They are

#define DBL_DIG          15
#define DBL_EPSILON     1.1102230246251568e-16

#define LDBL_DIG     15
#define LDBL_EPSILON     1.1102230246251568e-16L


------

#include <float.h>
#include <iostream>

int main()
{
   cout << DBL_DIG << endl;
   cout << DBL_EPSILON << endl;

   cout << LDBL_DIG << endl;
   cout << LDBL_EPSILON << endl;
}
0
 
LVL 1

Author Comment

by:glebspy
ID: 6201913
ok, I understand.

Do you have any help for my original question, namely why a long double doesn't seem to hold any more precision than a double (despite the fact that they have different #defines in float.h, which I'm not including) and whether and how I can change this situation.

0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 6201975
> namely why a long double doesn't seem to hold any more
precision

most likely due to what is reasonable to implement on the hardware on a given platform, i.e. 64 bit floating point  arithmetic is sensibly implemented in hardware on x86 platforms, but maybe 128 bit arithmetic is not.  

C++ itself says nothing other than sizeof(long double) >= sizeof(double) >= sizeof(float).  So, a compiler *could* have them all the same.

The only alternative that I know is to have code to deal with higher precision numbers.  There are abitrary precision number classes out there.
0
 
LVL 1

Author Comment

by:glebspy
ID: 6204730
The contents of my float.h file give me good reason to believe that >64bit precision is implemented in hardware on my platform.

The question is therefore not to do with hardware, unless you disagree with this conclusion.
0
 
LVL 1

Author Comment

by:glebspy
ID: 6351436
Thanks everyone ..
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

697 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question