bcdiv使用具有科学符号的非常小的浮点数导致“除以零".错误 [英] bcdiv using very small float with scientific notation cause "Division by zero" error
问题描述
使用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屋!