Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to assume floating point is represented using IEEE754 floats in C?

Tags:

Floating point is implementation defined in the C. So there isn't any guarantees.

Our code needs to be portable, we are discussing whether or not acceptable to use IEEE754 floats in our protocol. For performance reasons it would be nice if we don't have to convert back and forth between a fixed point format when sending or receiving data.

While I know that there can be differences between platforms and architectures regarding the size of long or wchar_t. But I can't seem to find any specific about the float and double.

What I found so far that the byte order maybe reversed on big endian platforms. While there are platforms without floating point support where a code containing float and double wouldn't even link. Otherwise platforms seem to stick to IEEE754 single and double precision.

So is it safe to assume that floating point is in IEEE754 when available?

EDIT: In response to a comment:

What is your definition of "safe"?

By safe I mean, the bit pattern on one system means the same on the another (after the byte rotation to deal with endianness).

like image 421
Calmarius Avatar asked Aug 12 '15 13:08

Calmarius


People also ask

What are the two main standards for floating-point representation?

There are three binary floating-point basic formats (encoded with 32, 64 or 128 bits) and two decimal floating-point basic formats (encoded with 64 or 128 bits). The binary32 and binary64 formats are the single and double formats of IEEE 754-1985 respectively.

How are floats represented in C?

Floating-point constants are positive unless they're preceded by a minus sign ( - ). In this case, the minus sign is treated as a unary arithmetic negation operator. Floating-point constants have type float , double , or long double . The Microsoft C compiler internally represents long double the same as type double .

What representation does IEEE 754 floating-point use to store negative floating-point values?

IEEE Standard 754 floating point is the most common representation today for real numbers on computers, including Intel-based PC's, Macs, and most Unix platforms. This is as simple as the name. 0 represents a positive number while 1 represents a negative number.

What are the three fields of floating-point representation?

There are three standard types in IEEE floating point arithmetic: single precision, double precision and extended precision.


1 Answers

Essentially all architectures in current non-punch-card use, including embedded architectures and exotic signal processing architectures, offer one of two floating point systems:

  • IEEE-754.
  • IEEE-754 except for blah. That is, they mostly implement 754, but cheap out on some of the more expensive and/or fiddly bits.

The most common cheap-outs:

  • Flushing denormals to zero. This invalidates certain sometimes-useful theorems (in particular, the theorem that a-b can be exactly represented if a and b are within a factor of 2), but in practice it's generally not going to be an issue.
  • Failure to recognize inf and NaN as special. These architectures will fail to follow the rules regarding inf and NaN as operands, and may not saturate to inf, instead producing numbers that are larger than FLT_MAX, which will generally be recognized by other architectures as NaN.
  • Proper rounding of division and square root. It's a whole lot easier to guarantee that the result is within 1-3 ulps of the exact result than within 1/2 ulp. A particularly common case is for division to be implemented as reciprocal+multiplication, which loses you one bit of precision.
  • Fewer or no guard digits. This is an unusual cheap-out, but means that other operations can be 1-2 ulps off.

BUUUUT... even those except for blah architectures still use IEEE-754's representation of numbers. Other than byte ordering issues, the bits describing a float or double on architecture A are essentially guaranteed to have the same meaning on architecture B.

So as long as all you care about is the representation of values, you're totally fine. If you care about cross-platform consistency of operations, you may need to do some extra work.

EDIT: As Chux mentions in the comments, a common extra source of inconsistency between platforms is the use of extended precision, such as the x87's 80-bit internal representation. That's the opposite of a cheap-out, and (with proper treatment) fully conforms to both IEEE-754 and the C standard, but it will likewise cause results to differ between architectures, and even between compiler versions and following apparently minor and unrelated code changes. However: a particular x86/x64 executable will NOT produce different results on different processors due to extended precision.

like image 161
Sneftel Avatar answered Oct 06 '22 08:10

Sneftel