-1

I'm trying to do some very simple math and for a specific set of numbers, it just isn't coming out right.

This is for a WooCommerce payment gateway. First, I get the cart total, which should be a float but for some weird reason got reported as a string in my debug code, so I forced it into a float just to be safe. Then I get the subunits, which is an Integer. I feel like multiplying a Float and an Int should be fine but anyway, I cast it because this was giving me so many problems. Then, I multiply them. Finally, I cast it to Integer as it should be a whole number anyway.

FWIW, subunits is always 100, so the result should be expressing a 2-decimal amount as an integer. 54.99 should be 5499, 12.50 should be 1250, and so on. This simple math always works, except when the total is 66.10, which always gives me 6609 for some reason.

    $total = floatval($this->order->get_total());
    $subunits = floatval($this->number_of_subunits_in_currency);
    $amount = $total * $subunits;
    $amount_int = intval($amount);
    WC_Gateway_XXX::log( sprintf( __( '$total is %f(%s), and $subunits is %f(%s).  the float product is %f(%s) and the intval is %u(%s)', 'flywire-payment-gateway' ), $total, gettype($total), $subunits, gettype($subunits), $amount, gettype($amount), $amount_int, gettype($amount_int) ) );

    // Serialize order info into JSON
    $settings                 = array();
    $settings['amount']       = $amount_int;

    WC_Gateway_XXX::log( sprintf( __( '$settings[\'amount\'] is %u(%s)', 'xxx-payment-gateway' ), $settings['amount'], gettype($settings['amount']) ) );

When I run the above code, I get the follow debug logs:

$total is 66.100000(double), and $subunits is 100.000000(double). the float product is 6610.000000(double) and the intval is 6609(integer)

$settings['amount'] is 6609(integer)

For all other numbers, it works. But for some reason, it's calculating the intval of 6610.000000 as 6609.

T Nguyen
  • 3,309
  • 2
  • 31
  • 48

1 Answers1

-1

floats are notoriously unreliable, and casting a float to an int leaves all sorts of options open to the interpreter. you're forcing a square peg into a round hole and asking the system to do its best, really. Instead, you could take control of how you want it. e.g. How about multiplying by 100 and truncating?

increddibelly
  • 1,221
  • 1
  • 15
  • 25