我似乎无法在php.net文档中找到解释以下结果的任何内容:

$php -r 'var_dump(bcsub("0.3", "0.2", 4));'

string(6) "0.1000"

$php -r 'var_dump(bcmul("0.3", "0.2", 4));'

string(4) "0.06"

减法结果正是我所期望的那样(我指定了一个4位数的刻度,它在结果中给了我一个).乘法结果不是(我指定了一个4位数的刻度,但它在结果中给了我一个2位数的刻度).为什么不同?

注意:我已经知道如何使用number_format()了,我也知道0.06 === 0.0600数学.我只对理解为什么BC Math在结果的规模方面表现出不同的行为感兴趣.

注意#2:如上所述,number_format()不是这个问题的答案,所引用的“重复问题”中使用的答案都建议使用number_format().我完全知道这个函数可以用来将数字格式化为指定的精度.我只是想知道为什么这些函数的返回值有不同的比例,而不是如何修复它们.

解决方法:

PHP的BCMath函数bcmul中存在一个错误.从PHP 5.5.7开始,它仍然存在,这是撰写本文时的最新稳定版本.

如果你是browse the source code(PHP 5.5的BCMath recmul.c),你会看到相关的功能:

void

bc_multiply (bc_num n1, bc_num n2, bc_num *prod, int scale TSRMLS_DC)

{

bc_num pval;

int len1, len2;

int full_scale, prod_scale;

/* Initialize things. */

len1 = n1->n_len + n1->n_scale;

len2 = n2->n_len + n2->n_scale;

full_scale = n1->n_scale + n2->n_scale;

prod_scale = MIN(full_scale,MAX(scale,MAX(n1->n_scale,n2->n_scale)));

/* Do the multiply */

_bc_rec_mul (n1, len1, n2, len2, &pval, full_scale TSRMLS_CC);

/* Assign to prod and clean up the number. */

pval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );

pval->n_value = pval->n_ptr;

pval->n_len = len2 + len1 + 1 - full_scale;

pval->n_scale = prod_scale;

_bc_rm_leading_zeros (pval);

if (bc_is_zero (pval TSRMLS_CC))

pval->n_sign = PLUS;

bc_free_num (prod);

*prod = pval;

}

注意:“scale”一词是指分隔符后面的位数.

看一下分配prod_scale的行.当您调用bcmul(“0.3”,“0.2”,4)时,遍历代码,我们看到:prod_scale = MIN(2,MAX(4,MAX(1,1)));,因此prod_scale被赋值2.

并且,正如预期的那样,该函数返回小数位后的两位而不是四位数的值.与其他BCMath PHP函数不同(例如,参见PHP 5.5的BCMath doaddsub.c的第63-98行),在此函数的逻辑中没有任何地方附加尾随零.

我已将此问题和补丁提交给PHP错误跟踪系统(#66364).

标签:php,bcmath

来源: https://codeday.me/bug/20190529/1175597.html

php不等于指定数字,php – 为什么bcmul返回的数字与我指定的数字不同?相关推荐

  1. 求两个数字的乘积,如果大于0,说明两个数字同号,如果小于0,说明两个数字异号,如果等于0,说明其中一个是0

    学了java基础东西,就写了这个编程,求两个数字的乘积,如果大于0,说明两个数字同号,如果小于0,说明两个数字异号,如果等于0,说明其中一个是0 首先程序要求我们输入两个数字,我就用了Scanner来 ...

  2. * 有1、2、3、4四个数字,能组成多少个互不相同且无重复数字的三位数? * 把这些数都输出出来,并且输出总共的个数。

    package Day03;import java.util.ArrayList;/*** 第五题:* 有1.2.3.4四个数字,能组成多少个互不相同且无重复数字的三位数?* 把这些数都输出出来,并且 ...

  3. python编写一个函数判断一个数是否为素数是则返回yes_编写函数isPrime,判断一个数字是否为素数,是则返回字符串 YES ,否则返回字符串 NO 。_学小易找答案...

    [填空题]语句 x = (3,) 执行后x的值为_______________. [填空题]字典对象的___________方法可以获取指定"键"对应的"值", ...

  4. 以太坊数字资产的发行和流通:以太坊上的数字资产定义、ERC 20代币合约标准、ERC 20标准接口、ERC 721代币合约标准、

    第七章 文章目录 第七章 一.以太坊上的数字资产定义 二.发行和流通 三.ERC 20代币合约标准 1.ERC 20标准接口 2.现有的ERC 20标准代币 三.ERC 721代币合约标准 1.标准定 ...

  5. php 字母数字下划线,CTF踩坑PHP编写一个不包含数字字母和下划线的后门

    首先要了解一下php中异或的用法 先看以下代码 echo "A"^"?"; ?> 运行结果 图片.png 我们可以看到,输出的结果是字符"~&q ...

  6. 数字积分法直线插补c语言程序,数控课程设计(数字积分法第二象限直线插补程序).docx...

    数字积分法第二象限直线插补程序设计 数字积分法是利用数字积分的方法,计算刀具沿各坐标轴的位移,使得刀具 沿着所加工的轮廓曲线运动 利用数字 积分原 理构成的插 补装置 称为数字积分 器,又称数 字微分 ...

  7. Excel里数字太长显示为科学计数法如何显示完整数字

    Excel里数字太长显示为科学计数法如何显示完整数字 注意:以下测试都是在macos的Microsoft Excel for Mac的16.53版本中实际测试的,在windows中应该也是一样的. 一 ...

  8. 求数字是几位数,顺序以及逆序输出各位数字

    给一个不多于5位的正整数,要求: 1.求出它是几位数: 2.分别输出每一位数字: 3.按逆序输出各位数字,例如原数为321,应输出123. 代码如下 #include<stdio.h> # ...

  9. 共享数字经济之光!世界互联网大会重磅发布“30位新生代数字经济人才”

    目前,全球经济进入深度调整的新阶段,全球信息化也进入了全面渗透.深度融合的新时期,中国数字经济异军突起,正成为创新经济发展方式的强大动力. 全球经济的快速发展使得本次数字经济人才的竞争显得尤为激烈,经 ...

最新文章

  1. vs code 列编辑模式
  2. keras如何解决局部最小问题
  3. 基因对智力的预测能力不到7%,别迷信它
  4. EasyUI表单验证,自定义插件验证,自定义js插件验证,远程验证,常见手机号,中英文,qq等验证规则验证...
  5. EF 关系规则(一对一、一对多、多对多...)
  6. CMake 构建项目Android NDK项目基础知识
  7. SQL Server日期格式转换大全
  8. 到底是无线最难?还是核心网最难?
  9. java录入会员信息_Java编程语言基础 第三章 实现会员信息录入功能
  10. Python list 初始化技巧
  11. (大一)——自学计划
  12. EXP-00003解决
  13. Uniwebview2插件常见问题以及刘海屏屏幕适配,屏幕旋转的解决方案
  14. 五、Matlab 画图——万能的plot函数
  15. 华为c语言笔试题下载,2005年华为招聘--C语言笔试试题
  16. PS曲线-进阶教程(深入理解PS曲线)
  17. React Toolkit使用
  18. Google Earth Engine ——边界线识别!
  19. python交互数据_Python用户交互以及数据类型
  20. 路由器基本设置(一)

热门文章

  1. 艾兹格·迪科斯彻(Edsger Wybe Dijkstra)
  2. python 爬虫下载ico
  3. 盛迈坤电商:店铺简介写应该注意什么
  4. 在windows中用java执行DOS命令arp -a获取已知MAC对应的ip地址
  5. 如何比较两幅图的相似度
  6. pipenv 命令笔记
  7. 实现按钮边框动画+摩天轮旋转动画+水印实现
  8. 【Unity】零基础入门教程整理
  9. 2019年CVTE 嵌入式软件 秋招笔试 编程题目
  10. 虚拟机提示内部错误解决方法