Current Location: Home> Latest Articles> What’s the Difference Between "f" and "d" in PHP’s pack Function? Have You Fallen into Floating-Point Precision Traps?

What’s the Difference Between "f" and "d" in PHP’s pack Function? Have You Fallen into Floating-Point Precision Traps?

M66 2025-06-23

In PHP, the pack function is a very practical tool used to pack data into binary strings according to a specified format, often utilized in network transmission, file storage, and similar contexts. Particularly when dealing with floating-point numbers, pack provides two format codes: "f" and "d". Although they appear similar, there are essential differences between them. Today, let's take a closer look at these two and the floating-point precision traps you might have stepped into.

A Brief Review of the pack Function

The basic usage of the pack function is:

pack(string $format, mixed ...$values): string

It converts the subsequent arguments into binary data based on the format string.

Among them, common floating-point format codes include:

  • "f": single-precision floating-point number (float, 4 bytes)

  • "d": double-precision floating-point number (double, 8 bytes)

Differences Between "f" and "d"

1. Different Data Sizes

  • "f" corresponds to a 4-byte single-precision floating-point number, that is, the float type, following the IEEE 754 32-bit floating-point format.

  • "d" corresponds to an 8-byte double-precision floating-point number, that is, the double type, following the IEEE 754 64-bit floating-point format.

This means "d" can represent a wider range and higher precision of floating-point numbers, while "f" takes less storage space but with limited precision.

2. Differences in Precision and Numeric Range

  • Single-precision floating-point numbers ("f") have approximately 7 significant digits of precision.

  • Double-precision floating-point numbers ("d") have about 15-16 significant digits of precision.

If you need highly accurate floating-point data, it is recommended to use "d".

3. Compatibility and Platform Dependence

The floating-point formats in pack are affected by the machine's byte order (endianness). Although most systems use little-endian, special care is needed during cross-platform transmission.

Example of Floating-Point Precision Trap

<?php
$value = 0.1 + 0.2;
<p>$packed_f = pack("f", $value);<br>
$packed_d = pack("d", $value);</p>
<p>echo "Original value: $value\n";<br>
echo "Single-precision packed hex: ".bin2hex($packed_f)."\n";<br>
echo "Double-precision packed hex: ".bin2hex($packed_d)."\n";<br>

Sample output:

Original value: 0.3
Single-precision packed hex: 9a99993e
Double-precision packed hex: 9a9999999999b93f

You can see that although the input is 0.3, the binary representations for single and double precision differ. This is because floating-point numbers cannot precisely represent some decimal fractions, and single precision has larger errors.

Practical Recommendations

  • When storing or transmitting high-precision floating-point numbers, prefer "d".

  • Use "f" to save space when precision requirements are not high.

  • When dealing with network protocols or file formats, clearly follow the floating-point format specified by the protocol to avoid misunderstandings.

  • For cross-platform applications, consider byte order issues and ensure consistent endianness when using pack and unpack.

Related Resources

Official PHP manual page for the pack function: