31

int is usually 32 bits, but in the standard, int is not guaranteed to have a constant width. So if we want a 32 bit int we include stdint.h and use int32_t.

Is there an equivalent for this for floats? I realize it's a bit more complicated with floats since they aren't stored in a homogeneous fashion, i.e. sign, exponent, significand. I just want a double that is guaranteed to be stored in 64 bits with 1 sign bit, 10 bit exponent, and 52/53 bit significand (depending on whether you count the hidden bit).

mskfisher
3,4124 gold badges37 silver badges50 bronze badges
asked Aug 26, 2009 at 0:55
9
  • Typically the number of bits for an int is needed because it is encoding some sort of object flags. Why do you need assurances on the precision of your floats? In most cases I've seen people tend to overstate the importance of the sizes of random variables. Often you'd be better off using the machine's default word size than trying to squeeze out 3 bytes of memory or arbitrarily using 32 bit values. Commented Aug 26, 2009 at 1:09
  • @Andrew-Khosravian I'm writing a scripting language, and I'd like to be able to make type-size guarantees to my users. That makes code written in my scripting language more portable. Commented Aug 26, 2009 at 1:35
  • 2
    Portability is fine, but you need to draw the line somewhere - after all, you're probably not expecting your scripting language to run on a PDP-11. Very few platforms do not support IEEE 754, and if that is supported, then it is a reasonable assumption that double is indeed 64 bits (since it's a double-precision floating point value) - and on the off chance that it is not, build in a sanity check so users can report it and you can handle that platform separately. If the platform doesn't support IEEE 754, you're not going to get that representation anyway unless you implement it yourself. Commented Aug 26, 2009 at 2:50
  • int is guaranteed to be at least 16 bits, and long int at least 32 bits (although it's actually defined in terms of the range of values representable) - so if you want a variable that can store any integer from -2147483647 to 2147483647, long int is fine. Commented Aug 26, 2009 at 7:16
  • @caf And if I want a variable that can store exactly 32 bits cross-platform? int32_t. Commented Aug 26, 2009 at 15:53

7 Answers 7

7

According to the current C99 draft standard, annex F, that should be double. Of course, this is assuming your compilers meet that part of the standard.

For C++, I've checked the 0x draft and a draft for the 1998 version of the standard, but neither seem to specify anything about representation like that part of the C99 standard, beyond a bool in numeric_limits that specifies that IEEE 754/IEC 559 is used on that platform, like Josh Kelley mentions.

Very few platforms do not support IEEE 754, though - it generally does not pay off to design another floating-point format since IEEE 754 is well-defined and works quite nicely - and if that is supported, then it is a reasonable assumption that double is indeed 64 bits (IEEE 754-1985 calls that format double-precision, after all, so it makes sense).

On the off chance that double isn't double-precision, build in a sanity check so users can report it and you can handle that platform separately. If the platform doesn't support IEEE 754, you're not going to get that representation anyway unless you implement it yourself.

answered Aug 26, 2009 at 1:11
3
  • I disagree that IEEE 754 works quite nicely, it is well entrenched so there is not much that can be done about ot. I do agree that what you want is double and you want to add a sanity check that will fail if someone finds a compiler that has a double that is the wrong size. Commented Aug 28, 2009 at 20:03
  • @dwelch: I'm not saying it doesn't have it's share of issues, or that it is always the best choice, but unless you have a need to be extremely precise or otherwise have very specialized needs when it comes to floating-point, IEEE 754 tends to do the trick, without being exceptionally slow. Commented Aug 28, 2009 at 21:51
  • agreed, the format is fine it is all the rules on rounding and exceptions that are the problem, making it so that few if any implementations are correct. Something between IEEE 754 and the TI DSP format would be idea as the TI DSP format has zero features (but is super fast and easy to implement and get right) Commented Aug 29, 2009 at 16:12
6

While I don't know of a type that guarantees a particular size and format, you do have a few options in C++. You can use the <limits> header and its std::numeric_limits class template to find out the size of a given type, std::numeric_limits::digits tells you the number of bits in the mantissa, and std::numeric_limits::is_iec559 should tell you whether the type follows the IEEE format. (For sample code that manipulates IEEE numbers at the bit level, see the FloatingPoint class template in Google Test's gtest-internal.h.)

answered Aug 26, 2009 at 1:19
3

From C++23 standard (ISO/IEC 14882:2023) there is <stdfloat>.

cppreference.com mentions the following:

namespace std {
 #if defined(__STDCPP_FLOAT16_T__)
 using float16_t = /* implementation-defined */;
 #endif
 #if defined(__STDCPP_FLOAT32_T__)
 using float32_t = /* implementation-defined */;
 #endif
 #if defined(__STDCPP_FLOAT64_T__)
 using float64_t = /* implementation-defined */;
 #endif
 #if defined(__STDCPP_FLOAT128_T__)
 using float128_t = /* implementation-defined */;
 #endif
 #if defined(__STDCPP_BFLOAT16_T__)
 using bfloat16_t = /* implementation-defined */;
 #endif
}

I am not aware of a C equivalent. However, you could try something like what is suggested here: https://stackoverflow.com/a/72440929/9962617

answered Sep 20, 2023 at 10:18
1

The other issue is representation of floating point numbers. This is usually based on the hardware on which you are running (but not always). Most system are using IEEE 754 Float point standards, but other can have their own standards as well (an example would be a VAX computer).

Wikipedia explaination of IEEE 754 http://en.wikipedia.org/wiki/IEEE_754-2008

answered Aug 26, 2009 at 1:15
1

There's no variation in float/double that I'm aware of. Float has has been 32 bits for ages and double has been 64. Floating point semantics are pretty complicated, but there do exist constants in

#include <limits>

boost.numeric.bounds is a simpler interface if you don't need everything in std::numeric_limits

answered Aug 26, 2009 at 1:17
2
  • This isn't true across platforms. Commented Aug 26, 2009 at 1:48
  • I've seen one compiler (LCC?) that made both float and double 64-bit types. Commented Jul 3, 2010 at 1:37
0

Unfortunately, that's not guaranteed either. You have to check numeric_limits< T > in <limits>.

But then again, I've never heard of an implementation where a double wasn't 64 bits long. If you wanted to just assume, you'd probably get away with it.

answered Aug 26, 2009 at 1:08
-4

One of the biggest problems with these kind of "fixed width types" is that it's so easy to get it wrong. You probably didn't want a 32 bits integer. What's the point? WHat you did want is an integer type that can store at least 1>>31. That's long int. You don't even need <stdint.h> for that.

Similarly, your scripting language can implement an FP type that will work as long as the underlying C++ float is at least 32 bits. Note that this still doesn't give you precise behavior. I'm fairly certain C++ doesn't guarantee -1.0/-3.0==1.0/3.0

answered Aug 26, 2009 at 10:32
4
  • No, I definitely do want a 32 bit integer. There are a many languages that make guarantees about the sizes of their basic types (C# and Java are two examples). "The point" as you call it, is consistent behavior on all platforms Commented Aug 26, 2009 at 15:44
  • Sorry, but you are missing the point. You want your scripting language to have a precisely-32 bits type. That in no way requires you to use a C++ type having exactly 32 bits. You probably also want guaranteed overflow, guranteed behavior of %, etc. So you'er going to reimplement the math anyway. It's trivial then to make this matah modulo 2^32. Commented Aug 27, 2009 at 8:40
  • 1
    No, that's int_least32_t, not long int. Commented Jul 3, 2010 at 1:47
  • @dan04: check the specs. char is at least 8 bits, int at least 16, and long at least 32. Commented Jul 5, 2010 at 7:00

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.