Is a 32 bit normalized floating point number that hasn't been operated on, same on any platform/compiler?
Asked Answered
P

2

5

For example:

float a = 3.14159f;

If I was to inspect the bits in this number (or any other normalized floating point number), what are the chances that the bits are different in some other platform/compiler combination, or is that possible?

Providenciaprovident answered 25/4, 2016 at 17:40 Comment(6)
C++ does not even define the number of bits to store a float (only the minimum), so yes it does depend on compiler and platformWeinert
C++ does not even define the number of bits to store in an int (only the minimum), so even the bits in int = -1 depends on the platform.Schach
Are you interested in a some concrete platform/compiler combinations? On some platforms there is even no floating point support.Allisonallissa
@Drop, those are not conforming implementations. The standard requires floating point types to be supported.Devour
Isn't there a canonical duplicate of this somewhere?Kimono
You need to check your compiler and OS to see if it is using IEEE floating points. If it is then you will get the same value on any platform that supports it were it is being used by the compiler. You can check this by checking the numeric traits: en.cppreference.com/w/cpp/types/numeric_limits/is_iec559 Its usally true for floats/doubles but you MUST check.Roussel
W
6

Your question can be rephrased as: Will the final assertion in the following code always be upheld, no matter what platform you run it on?

#include <cassert>
#include <cstring>
#include <cstdint>
#include <limits>
#if __cplusplus < 201103L // no static_assert prior to C++11
#define static_assert(a,b) assert(a)
#endif
int main() {
  float f = 3.14159f;
  std::uint32_t i = 0x40490fd0;// IEC 659/IEEE 754 representation
  static_assert(std::numeric_limits<float>::is_iec559, "floating point must be IEEE 754");
  static_assert(sizeof(f) == sizeof(i), "float must be 32 bits wide");
  assert(std::memcmp(&f, &i, sizeof(f)) == 0);
}

Answer: There's nothing in the C++ standard that guarantees that the assertion will be upheld. Yet, on most sane platforms the assertion will hold and the code won't abort, no matter if the platform is big- or little-endian. As long as you only care that your code works on some known set of platforms, it'll be OK: you can verify that the tests pass there :)

Realistically speaking, some compilers might use a sub-par decimal-to-IEEE-754 conversion routine that doesn't properly round the result, so if you specify f to enough digits of precision, it might be a couple of LSBs of mantissa off from the value that would be nearest to the decimal representation. And then the assertion won't hold anymore. For such platforms, you might wish to test a couple mantissa LSBs around the desired one.

Wendiwendie answered 25/4, 2016 at 17:46 Comment(3)
I understood the question a bit different, as asking for different bits on different platforms, not differences in the bits on the same platformWeinert
@tobi303, the answer assumes that 0x40490fd0 is a fixed bit pattern, and so compares the bits in that value with the bits in the float ... i.e. it is talking about different bits on different platforms.Devour
@JonathanWakely ah ok, I had to look twice to understand it. After reading it again (especially the "Will the following code ever assert?" part) I got the ideaWeinert
K
8

Not necessarily: The c++ standard doesn't define floating point representation (it doesn't even define the representation of signed integers), although most platforms probably orient themselves on the same IEEE standard (IEEE 754-2008?).

Kimono answered 25/4, 2016 at 17:43 Comment(0)
W
6

Your question can be rephrased as: Will the final assertion in the following code always be upheld, no matter what platform you run it on?

#include <cassert>
#include <cstring>
#include <cstdint>
#include <limits>
#if __cplusplus < 201103L // no static_assert prior to C++11
#define static_assert(a,b) assert(a)
#endif
int main() {
  float f = 3.14159f;
  std::uint32_t i = 0x40490fd0;// IEC 659/IEEE 754 representation
  static_assert(std::numeric_limits<float>::is_iec559, "floating point must be IEEE 754");
  static_assert(sizeof(f) == sizeof(i), "float must be 32 bits wide");
  assert(std::memcmp(&f, &i, sizeof(f)) == 0);
}

Answer: There's nothing in the C++ standard that guarantees that the assertion will be upheld. Yet, on most sane platforms the assertion will hold and the code won't abort, no matter if the platform is big- or little-endian. As long as you only care that your code works on some known set of platforms, it'll be OK: you can verify that the tests pass there :)

Realistically speaking, some compilers might use a sub-par decimal-to-IEEE-754 conversion routine that doesn't properly round the result, so if you specify f to enough digits of precision, it might be a couple of LSBs of mantissa off from the value that would be nearest to the decimal representation. And then the assertion won't hold anymore. For such platforms, you might wish to test a couple mantissa LSBs around the desired one.

Wendiwendie answered 25/4, 2016 at 17:46 Comment(3)
I understood the question a bit different, as asking for different bits on different platforms, not differences in the bits on the same platformWeinert
@tobi303, the answer assumes that 0x40490fd0 is a fixed bit pattern, and so compares the bits in that value with the bits in the float ... i.e. it is talking about different bits on different platforms.Devour
@JonathanWakely ah ok, I had to look twice to understand it. After reading it again (especially the "Will the following code ever assert?" part) I got the ideaWeinert

© 2022 - 2024 — McMap. All rights reserved.