Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7894693
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T07:27:39+00:00 2026-06-03T07:27:39+00:00

I’m implementing the Pythagorean means in PHP, the arithmetic and geometric means are a

  • 0

I’m implementing the Pythagorean means in PHP, the arithmetic and geometric means are a piece of cake but I’m having a really hard time coming up with a reliable harmonic mean implementation.

This is the WolframAlpha definition:

Harmonic Mean Definition from WolframAlpha


And this is the equivalent implementation in PHP:

function harmonicMeanV1()
{
    $result = 0;
    $arguments = func_get_args();

    foreach ($arguments as $argument)
    {
        $result += 1 / $argument;
    }

    return func_num_args() / $result;
}

Now, if any of the arguments is 0 this will throw a division by 0 warning, but since 1 / n is the same as n-1 and pow(0, -1) gracefully returns the INF constant without throwing any errors I could rewrite that to the following (it’ll still throw errors if there are no arguments, but lets ignore that for now):

function harmonicMeanV2()
{
    $arguments = func_get_args();
    $arguments = array_map('pow', $arguments, array_fill(0, count($arguments), -1));

    return count($arguments) / array_sum($arguments);
}

Both implementations work fine for most cases (example v1, v2 and WolframAlpha), but they fail spectacularly if the sum of the 1 / ni series is 0, I should get another division by 0 warning, but I don’t…

Consider the following set: -2, 3, 6 (WolframAlpha says it’s a complex infinite):

  1 / -2    // -0.5
+ 1 / 3     // 0.33333333333333333333333333333333
+ 1 / 6     // 0.16666666666666666666666666666667

= 0

However, both my implementations return -2.7755575615629E-17 as the sum (v1, v2) instead of 0.

While the return result on CodePad is -108086391056890000 my dev machine (32-bit) says it’s -1.0808639105689E+17, still it’s nothing like the 0 or INF I was expecting. I even tried calling is_infinite() on the return value, but it came back as false as expected.

I also found the stats_harmonic_mean() function that’s part of the stats PECL extension, but to my suprise I got the exact same buggy result: -1.0808639105689E+17, if any of the arguments is 0, 0 is returned but no checks are done to the sum of the series, as you can see on line 3585:

3557    /* {{{ proto float stats_harmonic_mean(array a)
3558       Returns the harmonic mean of an array of values */
3559    PHP_FUNCTION(stats_harmonic_mean)
3560    {
3561        zval *arr;
3562        double sum = 0.0;
3563        zval **entry;
3564        HashPosition pos;
3565        int elements_num;
3566    
3567        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a",  &arr) == FAILURE) {
3568            return;
3569        }
3570        if ((elements_num = zend_hash_num_elements(Z_ARRVAL_P(arr))) == 0) {
3571            php_error_docref(NULL TSRMLS_CC, E_WARNING, "The array has zero elements");
3572            RETURN_FALSE;
3573        }
3574    
3575        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos);
3576        while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&entry, &pos) == SUCCESS) {
3577            convert_to_double_ex(entry);
3578            if (Z_DVAL_PP(entry) == 0) {
3579                RETURN_LONG(0);
3580            }
3581            sum += 1 / Z_DVAL_PP(entry);
3582            zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos);   
3583        }
3584    
3585        RETURN_DOUBLE(elements_num / sum);
3586    }
3587    /* }}} */

This looks like a typical floating precision bug, but I can’t really understand the reason why since the individual calculations are quite precise:

Array
(
    [0] => -0.5
    [1] => 0.33333333333333
    [2] => 0.16666666666667
)

Is it possible to work around this problem without reverting to the gmp / bcmath extensions?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T07:27:40+00:00Added an answer on June 3, 2026 at 7:27 am

    You are correct. The numbers you are finding are an artifact of the peculiarities of floating-point arithmetic.

    Adding more precision will not help you. All you’re doing is moving the goal posts.

    The bottom line is that the calculations are done with finite precision. That means that at some point, an intermediate result will be rounded. That intermediate result is then no longer exact. The error propagates through the calculations, and eventually makes it into your final result. When the exact result is zero, you usually get a numeric result of around 1e-16 with double-precision numbers.

    This happens every time your calculation involves a fraction with a denominator that is not a power of 2.

    The only way around it is to express the calculations in terms of integers or rational numbers (if you can), and use an arbitrary precision integer package to do the calculations. This is what Wolfram|Alpha does.

    Note that the calculation of the geometric mean is not trivial, either. Try a sequence of 20 times 1e20. Since the numbers are all the same, the result should be 1e20. But what you’ll find is that the result is infinite. The reason is that the product of those 20 numbers (10e400) is outside the range of double-precision floating-point numbers, and so it’s set to infinity. The 20th root of infinity is still infinity.

    Finally, a meta-observation: the Pythogarian means really only make sense for positive numbers. What is the geometric mean of 3 and -3? Is it imaginary?? The chain of inequalities on the Wikipedia page you link to are only valid if all values are positive.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I want to count how many characters a certain string has in PHP, but
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
I would like to count the length of a string with PHP. The string
this is what i have right now Drawing an RSS feed into the php,
I have a French site that I want to parse, but am running into
I'm using v2.0 of ClassTextile.php, with the following call: $testimonial_text = $textile->TextileRestricted($_POST['testimonial']); ... and
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
We're building an app, our first using Rails 3, and we're having to build
I need to clean up various Word 'smart' characters in user input, including but

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.