What is the difference between double and int64_t in C/C++ for precision?

  • C/C++
  • Thread starter ORF
  • Start date
  • Tags
    Precision
In summary, Microsoft (and possibly others) have a __m128 data type that can be used with Streaming SIMD Extensions 2 (SSE2) intrinsics, but this is different from float, double, and long double.
  • #1
ORF
170
18
Hello

I am currently using double type for numbers with the format 6f8 (6 digits before the point, 8 digits after the point).

Double structure is enough for this format, or should I use int64_t instead?

Thank you in advance :)

Greetings.
PS: I tried with this example code, but the result it's a bit strange for me... (precision is lost for 4-digit double ? )
Code:
#include <iostream>
#include "stdint.h"

int main()
{
  std::cout << "check precision of Double vs uint64_t\n";
  uint64_t k(1);
  while( k < 1e14 )
  {
      k=k*3+1;
     //-- check precision of myDouble
     double myDouble( k/1e8);
     uint64_t test( 1e8 * myDouble );
     if( k != test ) std::cout << k << "\t" << test << std::endl;
    
  }
  return 0;
}
http://cpp.sh/8zqfx
The output I got is:
check precision of Double vs uint64_t
3280 3279
3812798742493 3812798742492
 
Technology news on Phys.org
  • #2
double is not a structure. It is an IEEE754 floating point type. Conversion in C++ is truncation so if you actual number comes out to be 3812798742492.999 then you will still get 3812798742492 when converted to uint64_t. Try printing out the double value too and see what happens.

BoB
 
  • #3
Hello

You were right: without conversion (truncation) it seems that the number is the same
Code:
#include <iostream>
#include "stdint.h"
#include <iomanip>
int main()
{
  std::cout << "check precision of Double vs uint64_t\n";
  uint64_t k(1);
  while( k < 1e14 )
  {
      k=k*3+1;
     //-- check precision of myDouble
     double myDouble( k/1e8);
     uint64_t test( 1e8 * myDouble );
     if( k != test ) std::cout << std::setprecision(16) << k << "\t" << myDouble*1e8 << std::endl;
     
  }
  return 0;
}

So, does it mean that no-digit is lost with 6f8 format using doubles? Where is the limit? (in cases that k > 1e15, the last digits are lost...)

Thank you for your time :)

Greetings
 
  • #4
IEEE754 has a 52 bit mantissa, good enough for 15 digits ((log10(2^52) = 15.6...), so 14 digits (6f8) shouldn't be an issue if you round instead of truncate.

Code:
#include <iostream>

typedef unsigned long long uint64_t;

int main()
{
    std::cout << "check precision of Double vs uint64_t\n";
    uint64_t k(1);
    while( k < 1e14 )
    {
        k=k*3+1;
        //-- check precision of myDouble
        double myDouble = k/1e8;    // 1e8 is a double
        uint64_t test = (uint64_t)( 1e8 * myDouble + 0.5);  // + 0.5 for round
        if( k != test ) std::cout << k << "\t" << test << std::endl;
    }
    return 0;
}
 
Last edited:
  • #5
Wait, your types are all wrong.

You can't just mix types like that, you have to cast them when you do any calculation or else division or multiplication with an integer will result in another integer THEN get cast as a double. You code is ambiguous as best.

Also, have you checked to see if long double is present in your compiler? It's not standard (it might be after c++11) but most compilers support it as either a 96 or 128 bit double. Use sizeof(long double) to check, it'll give you bytes.
 
  • #6
newjerseyrunner said:
Wait, your types are all wrong.
Which post are you replying to?
newjerseyrunner said:
You can't just mix types like that, you have to cast them when you do any calculation or else division or multiplication with an integer will result in another integer THEN get cast as a double. You code is ambiguous as best.

Also, have you checked to see if long double is present in your compiler? It's not standard (it might be after c++11) but most compilers support it as either a 96 or 128 bit double.
I don't think this is correct. Long ago, the Borland C/C++ compiler I had distinguished between double and long double as 64 bits and 80 bits, respectively. The Microsoft compiler I have now (VS 2015) supports both, but both are the same size - 64 bits.

Microsoft (and possibly others) have a __m128 data type that can be used with Streaming SIMD Extensions 2 (SSE2) intrinsics, but this is different from float, double, and long double.
newjerseyrunner said:
Use sizeof(long double) to check, it'll give you bytes.
 
  • #7
newjerseyrunner said:
Also, have you checked to see if long double is present in your compiler? It's not standard (it might be after c++11) but most compilers support it as either a 96 or 128 bit double. Use sizeof(long double) to check, it'll give you bytes.

Long double should be available in any C89 (or C90, C95, C99) compatible compiler. However technically long double could be equivalent to the float data type (it must not be worse than a double which must not be worse than a float). The C standards for floating point datatypes are very forgiving for doubles and long double so a compiler writer can implement a wide variety of solutions.

The range requirements for double/long double are for instance the same as for float (6 decimal digits) and precision requirements for double/long double are only specified as 10 decimal digits which is in-between the commonally used IEEE-754 binary32 (6 digit) and binary64 (15 digits) datatypes. I did some quick calculations and it looks like even 56 bits is actually overkill to satisfy the long double specification. So, usually float and double are IEEE-754 binary32 and binary64 respectivly but long double could be anything (but usually not worse than binary64)

This reminds me of an issue we had at work where some code failed because char turned out to be a 32 bit integer datatype on a DSP platform. It is an unusual but valid implementation ... the joys of the C standard.

If you want to marvel at it the C99 standards can be found here: http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf and the IEEE-754-2008 standard can be found here: http://www.csee.umbc.edu/~tsimo1/CMSC455/IEEE-754-2008.pdf
 
Last edited by a moderator:
  • #8
newjerseyrunner said:
Wait, your types are all wrong.
1e8 is a double (at least with Visual Studio, so in the case of k / 1e8, k gets promoted to a double. I updated post #4 with a comment to note this.

long double
The older 16 bit Microsoft compilers use 80 bit floating point format for long doubles, but 32/64 bit Microsoft/Visual Studio compilers use 64 bit floating point for long doubles, the same as regular doubles.
 

1. What is precision double in C/C++?

Precision double in C/C++ refers to a data type that allows for the storage and manipulation of floating-point numbers with a higher degree of precision compared to the standard float data type. It is typically represented using 64 bits and can store decimal numbers with up to 15-17 significant digits.

2. How is precision double different from float?

The main difference between precision double and float is the amount of storage space and precision. Precision double uses 64 bits to store data, while float uses only 32 bits. This allows for a larger range of values and more precise calculations with precision double.

3. When should I use precision double in my code?

Precision double should be used when dealing with calculations that require a higher level of precision, such as financial or scientific calculations. It is also useful when dealing with very large or very small numbers, as the larger range of values can prevent overflow or underflow errors.

4. How do I declare a precision double variable in C/C++?

To declare a precision double variable in C/C++, you can use the keyword "double" followed by the variable name. For example, "double myVar;" would declare a precision double variable named "myVar".

5. Are there any drawbacks to using precision double?

The main drawback of using precision double is that it requires more storage space compared to float. This can lead to slower performance and larger memory usage, especially in code that involves a large number of precision double variables. Additionally, precision double may not be necessary for all types of calculations, so it is important to consider whether the higher precision is needed before using it in your code.

Similar threads

  • Programming and Computer Science
Replies
20
Views
1K
  • Programming and Computer Science
Replies
3
Views
1K
  • Programming and Computer Science
Replies
1
Views
646
  • Programming and Computer Science
Replies
8
Views
1K
  • Programming and Computer Science
Replies
4
Views
13K
  • Programming and Computer Science
Replies
1
Views
2K
  • Programming and Computer Science
Replies
4
Views
8K
  • Programming and Computer Science
Replies
12
Views
3K
  • Programming and Computer Science
Replies
6
Views
1K
  • Programming and Computer Science
Replies
17
Views
2K
Back
Top