Skip to content

Floating point bug in range operation on Apple Silicon hardware #14140

Closed

Description

@judahnator

Description

The following code:

<?php
print_r(range(-0.03, 0.03, 0.01));

Resulted in this output:

Array
(
    [0] => -0.03
    [1] => -0.02
    [2] => -0.01
    [3] => 1.7347234759768E-18
    [4] => 0.01
    [5] => 0.02
)

But I expected this output instead:

Array
(
    [0] => -0.03
    [1] => -0.02
    [2] => -0.01
    [3] => 0
    [4] => 0.01
    [5] => 0.02
    [6] => 0.03
)

I tested this on a few devices with my peers. Every x86 processor we tested worked as expected, but reliably got the erroneous result using different Apple M2 devices.

PHP Version

PHP 8.3.6

Operating System

Sonoma 14.4.1

Activity

  1. SakiTakamachi commented on May 5, 2024

    @SakiTakamachi
    Member

    I'll investigate this issue.

  2. self-assigned this
    on May 5, 2024
  3. SakiTakamachi commented on May 6, 2024

    @SakiTakamachi
    Member

    The investigation is complete. This is probably an Apple bug.

    The following code:

    // double.c
    int main(void)
    {
        int i = 3;
        double v = 0.03;
        double v2 = 0.01;
    
        double ret = v - (i * v2);
    
        return 0;
    }
    

    compile:

    clang -o double -g double.c
    

    exec:

    ./double
    

    If this continues, nothing will be output, so debug with gdb:

    # gdb ./double
    
    ....
    
    (gdb) b main
    Breakpoint 1 at 0x724: file double.c, line 4.
    (gdb) run
    
    ....
    
    Breakpoint 1, main () at double.c:4
    4           int i = 3;
    (gdb) n
    5           double v = 0.03;
    (gdb) 
    6           double v2 = 0.01;
    (gdb) 
    8           double ret = v - (i * v2);
    (gdb) 
    10          return 0;
    (gdb) p ret
    $1 = -1.7347234759768071e-18
    (gdb) p v
    $2 = 0.029999999999999999
    (gdb) p v2
    $3 = 0.01
    (gdb) p i
    $4 = 3
    (gdb) p i * v2
    $5 = 0.029999999999999999
    (gdb) p v - (i * v2)
    $6 = 0
    

    We can see that the calculation result ret is incorrect.

  4. SakiTakamachi commented on May 6, 2024

    @SakiTakamachi
    Member

    However, I'm just trying to figure out if there's a workaround for this

  5. devnexen commented on May 6, 2024

    @devnexen
    Member

    If that helps, I have the same issue with my raspberry 4.

  6. erjotek commented on May 6, 2024

    @erjotek

    same problem occurred between 5.0 and 5.3.6 checking on 3v4l

  7. SakiTakamachi commented on May 6, 2024

    @SakiTakamachi
    Member

    Thanks. hmm, then, is this an arm-specific phenomenon? It might be a good idea to push the test code to Circle CI arm.

  8. SakiTakamachi commented on May 6, 2024

    @SakiTakamachi
    Member

    On a separate matter, I was investigating the behavior when using gcc and arm together.
    So I discovered by chance that this only happens when compiled with clang. Compiling with gcc gives normal results.

  9. youkidearitai commented on May 6, 2024

    @youkidearitai
    Contributor

    In M1 MacBook Air is reproduced.

    MacBook-Air-2:php-src tekimen$ sapi/cli/php -r 'print_r(range(-0.03, 0.03, 0.01));'
    Array
    (
        [0] => -0.03
        [1] => -0.02
        [2] => -0.01
        [3] => 1.7347234759768E-18
        [4] => 0.01
        [5] => 0.02
    )
    

    In Raspberry Pi 4 (build in GCC), result is bellow:

    tekimen@raspberrypi:~/src/php-src $ sapi/cli/php -r 'print_r(range(-0.03, 0.03, 0.01));'
    Array
    (
        [0] => -0.03
        [1] => -0.02
        [2] => -0.01
        [3] => 0
        [4] => 0.01
        [5] => 0.02
        [6] => 0.03
    )
    

    However, In Raspberry Pi 4 (build in clang), result is reproduced:

    tekimen@raspberrypi:~/src/php-src $ cat config.nice
    #! /bin/sh
    #
    # Created by configure
    
    CFLAGS='-g' \
    LDFLAGS='-v' \
    CC='clang' \
    './configure' \
    '--enable-debug' \
    '--enable-mbstring' \
    '--prefix=/home/tekimen/php83' \
    "$@"
    tekimen@raspberrypi:~/src/php-src $ sapi/cli/php -r 'print_r(range(-0.03, 0.03, 0.01));'
    Array
    (
        [0] => -0.03
        [1] => -0.02
        [2] => -0.01
        [3] => 1.7347234759768E-18
        [4] => 0.01
        [5] => 0.02
    )
    
  10. SakiTakamachi commented on May 6, 2024

    @SakiTakamachi
    Member

    The combination of intel and clang works fine.

  11. SakiTakamachi commented on May 6, 2024

    @SakiTakamachi
    Member
  12. SakiTakamachi commented on May 6, 2024

    @SakiTakamachi
    Member

    I was able to get an answer right away. This is a problem with clang's compilation flags, and if -ffp-contract=off is not specified, calculation results may be slightly different from those of gcc etc.

    Therefore, if you are building it yourself, please pass CFLAGS='-ffp-contract=off' in ./configure.

  13. youkidearitai commented on May 6, 2024

    @youkidearitai
    Contributor

    I confirmed correct behavior in M1 MacBook Air.

    MacBook-Air-2:php-src tekimen$ cat config.nice
    #! /bin/sh
    #
    # Created by configure
    
    CFLAGS='-ffp-contract=off' \
    './configure' \
    '--enable-mbstring' \
    '--enable-debug' \
    '--prefix=/Users/tekimen/php_master' \
    '--with-iconv=/opt/homebrew/opt/libiconv' \
    'PKG_CONFIG_PATH=/opt/homebrew/opt/icu4c/lib/pkgconfig' \
    '--enable-bcmath' \
    '--with-zlib' \
    '--enable-intl' \
    "$@"
    MacBook-Air-2:php-src tekimen$ sapi/cli/php -r 'print_r(range(-0.03, 0.03, 0.01));'
    Array
    (
        [0] => -0.03
        [1] => -0.02
        [2] => -0.01
        [3] => 0
        [4] => 0.01
        [5] => 0.02
        [6] => 0.03
    )
    
  14. github-actions commented on May 21, 2024

    @github-actions

    No feedback was provided. The issue is being suspended because we assume that you are no longer experiencing the problem. If this is not the case and you are able to provide the information that was requested earlier, please do so. Thank you.

  15. erjotek commented on May 21, 2024

    @erjotek

    @shivammathur Hi, do you plan to change this flag in yours brew packages?

  16. SakiTakamachi commented on May 21, 2024

    @SakiTakamachi
    Member

    This issue was resolved by the following PR:

    #14162

  17. shivammathur commented on May 21, 2024

    @shivammathur
    Member

    @erjotek

    @shivammathur Hi, do you plan to change this flag in yours brew packages?

    Yes, with the next releases.

  18. judahnator commented on May 21, 2024

    @judahnator
    Author

    Still having the problem, thanks GitHub actions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions