bcdiv使用具有科学符号的非常小的浮点数导致“除以零".错误 [英] bcdiv using very small float with scientific notation cause "Division by zero" error

查看:184
本文介绍了bcdiv使用具有科学符号的非常小的浮点数导致“除以零".错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用bcdiv,我无法使用科学计数法将小浮点数相除:

Using bcdiv, i can't divide with small float using scientific notation :

工作代码:

bcscale(30);
$a = '1' ;
$b = '0.00000001';
$result = bcdiv($a, $b);
var_dump($result);

结果:

string(20)"100000000.0000000000"

string(20) "100000000.0000000000"

无效代码:

bcscale(30);
$a =  '1' ;
$b =  '1e-8';
$result = bcdiv($a, $b);
var_dump($result);

结果:

警告:bcdiv(​​)[function.bcdiv]:零除 XX行NULL上的C:\ wamp \ www \ utilitaires \ test_bcdiv.php

Warning: bcdiv() [function.bcdiv]: Division by zero in C:\wamp\www\utilitaires\test_bcdiv.php on line XX NULL

如何以较少的精度损失正确地进行这种划分?

How can i do this division properly, with the less precision loss ?

推荐答案

这实际上是因为bcmath不支持科学计数法.手册中没有提到它,但是您可以看到,它在实现参数转换,它被命名为 :

That is because, actually, bcmath doesn't support scientific notation. It isn't mentioned in manuals, but as you can see, in it's implementation argument conversion is used, it's named php_str2num:

static void php_str2num(bc_num *num, char *str TSRMLS_DC)
{
    char *p;

    if (!(p = strchr(str, '.'))) {
        bc_str2num(num, str, 0 TSRMLS_CC);
        return;
    }

    bc_str2num(num, str, strlen(p+1) TSRMLS_CC);
}

,因此 bc_str2num :

bc_str2num (bc_num *num, char *str, int scale TSRMLS_DC)
{
  int digits, strscale;
  char *ptr, *nptr;
  char zero_int;

  /* Prepare num. */
  bc_free_num (num);

  /* Check for valid number and count digits. */
  ptr = str;
  digits = 0;
  strscale = 0;
  zero_int = FALSE;
  if ( (*ptr == '+') || (*ptr == '-'))  ptr++;  /* Sign */
  while (*ptr == '0') ptr++;            /* Skip leading zeros. */
  while (isdigit((int)*ptr)) ptr++, digits++;   /* digits */
  if (*ptr == '.') ptr++;           /* decimal point */
  while (isdigit((int)*ptr)) ptr++, strscale++; /* digits */
  if ((*ptr != '\0') || (digits+strscale == 0))
    {
      *num = bc_copy_num (BCG(_zero_));
      return;
    }

  /* Adjust numbers and allocate storage and initialize fields. */
  strscale = MIN(strscale, scale);
  if (digits == 0)
    {
      zero_int = TRUE;
      digits = 1;
    }
  *num = bc_new_num (digits, strscale);

  /* Build the whole number. */
  ptr = str;
  if (*ptr == '-')
    {
      (*num)->n_sign = MINUS;
      ptr++;
    }
  else
    {
      (*num)->n_sign = PLUS;
      if (*ptr == '+') ptr++;
    }
  while (*ptr == '0') ptr++;            /* Skip leading zeros. */
  nptr = (*num)->n_value;
  if (zero_int)
    {
      *nptr++ = 0;
      digits = 0;
    }
  for (;digits > 0; digits--)
    *nptr++ = CH_VAL(*ptr++);

  /* Build the fractional part. */
  if (strscale > 0)
    {
      ptr++;  /* skip the decimal point! */
      for (;strscale > 0; strscale--)
    *nptr++ = CH_VAL(*ptr++);
    }
}

-不难看出它将以科学计数法失败(被充分评论).也许文档需要更新(隐式提及).

-not hard to see that it will fail on scientific notation (well-commented). Perhaps documentation needs to be updated (to mention that implicitly).

可能的解决方案是在应用bcmath函数之前将字符串转换为纯视图

Possible solution will be to convert your string to plain view before applying bcmath functions

这篇关于bcdiv使用具有科学符号的非常小的浮点数导致“除以零".错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆