PHP浮点数的一个常见问题

 更新时间:2016年11月25日 14:59  点击:1514
在php中浮点数是一个非常有用的数据类型了,但是他同样也给我们带来很多的细节问题,下面我来举个实例来分析PHP浮点数的一个常见问题

先看看这段代码:

 代码如下 复制代码

<?php
    $f = 0.58;
    var_dump(intval($f * 100)); //为什么输出57
?>

为什么输出是57?

我相信有很多的同学有过这样的疑问,bugs.php.net上经也常有人问。

要搞明白这个原因, 首先我们要知道浮点数的表示(IEEE 754):

浮点数, 以64位的长度(双精度)为例, 会采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).

符号位:最高位表示数据的正负,0表示正数,1表示负数。

指数位:表示数据以2为底的幂,指数采用偏移码表示

尾数:表示数据小数点后的有效数字.

这里的关键点就在于, 小数在二进制的表示, 关于小数如何用二进制表示, 大家可以百度一下, 我这里就不再赘述, 我们关键的要了解, 0.58 对于二进制表示来说, 是无限长的值(下面的数字省掉了隐含的1)..


0.58的二进制表示基本上(52位)是: 0010100011110101110000101000111101011100001010001111
0.57的二进制表示基本上(52位)是: 0010001111010111000010100011110101110000101000111101

而两者的二进制, 如果只是通过这52位计算的话,分别是:


0.58 -> 0.57999999999999996
0.57 -> 0.56999999999999995

至于0.58 * 100的具体浮点数乘法, 我们不考虑那么细, 有兴趣的可以看(Floating point), 我们就模糊的以心算来看… 0.58 * 100 = 57.999999999

那你intval一下, 自然就是57了….

可见, 这个问题的关键点就是: “你看似有穷的小数, 在计算机的二进制表示里却是无穷的”

so, 不要再以为这是PHP的bug了, 这就是这样的.

在已知URL参数的情况下,我们可以根据自身情况采用$_GET来获取相应的参数信息($_GET[\\\'name\\\']);那,在未知情况下如何获取到URL上的参数信息呢?

第一种、利用$_SERVER内置数组变量

相对较为原始的$_SERVER['QUERY_STRING']来获取,URL的参数,通常使用这个变量返回的会是类似这样的数据:name=tank&sex=1

如果需要包含文件名的话可以使用$_SERVER["REQUEST_URI"](返回类似:/index.php?name=tank&sex=1)


第二种、利用pathinfo内置函数
01 <?php
02 $test = pathinfo("http://localhost/index.php");
03 print_r($test);
04 /*
05 结果如下
06 Array
07 (
08     [dirname] => http://localhost //url的路径
09     [basename] => index.php  //完整文件名
10     [extension] => php  //文件名后缀
11     [filename] => index //文件名
12 )
13 */
14 ?>


第三种、利用parse_url内置函数
01 <?php
02 $test = parse_url("http://localhost/index.php?name=tank&sex=1#top");
03 print_r($test);
04 /*
05 结果如下
06 Array
07 (
08     [scheme] => http //使用什么协议
09     [host] => localhost //主机名
10     [path] => /index.php //路径
11     [query] => name=tank&sex=1 // 所传的参数
12     [fragment] => top //后面根的锚点
13 )
14 */
15 ?>


第四种、利用basename内置函数
1 <?php
2 $test = basename("http://localhost/index.php?name=tank&sex=1#top");
3 echo $test;
4 /*
5 结果如下
6 index.php?name=tank&sex=1#top
7 */
8 ?>


另外,还有就是自己通过正则匹配的处理方式来获取需要的值了。这种方式较为精确,效率暂不考虑。。。

下面拓展实践下正则处理方式:
01 <?php
02 preg_match_all("/(\w+=\w+)(#\w+)?/i","http://localhost/index.php?name=tank&sex=1#top",$match);
03 print_r($match);
04 /*
05 结果如下
06 Array
07 (
08     [0] => Array
09         (
10             [0] => name=tank
11             [1] => sex=1#top
12         )
13     [1] => Array
14         (
15             [0] => name=tank
16             [1] => sex=1
17         )
18     [2] => Array
19         (
20             [0] =>
21             [1] => #top
22         )
23 )
24 */
25 ?>


路途漫漫...还有待继续挖掘...

本文章介绍从url带参数传值与在表单中传值的获取方法,希望本文章对各位同学会带来帮助。

例子、单表单内容发送和接收

我们都是如果要实现内容发送或者接收我们首先都需要一个表单也就是form标签 下面这个是前端的html代码

 代码如下 复制代码

<form  action="1.php">
<p>Get 发送方式:
<input type="text" name="wz"/></p>

<p>Post 发送发送:
<input type="text" name="wz1"/></p>

<input type="submit" value="OK"/>
</form>

 

后台的php就是从上面的name内的值获取需要的内容

 

 代码如下 复制代码

<?php
$a = $_GET ['wz'];
if($a==null){echo "对方没输入"."</br>";}else{
echo "我是GET接收方式:".$a."</br>";}

$b = $_GET ['wz1'];
if($b==null){echo "对方没输入"."</br>";}else{
echo "我是POST接收方式:".$b."</br>";}
?>


这里的php意思以get模式来获取标签内属性name里面的值

然而echo 在php中就是打印出来 if就是先加以判断~ 注意:如果表单是post传值我们必须使用$_POST才可以接受数据

例子、url传值

 这个是要发送的php代码

   

 代码如下 复制代码

<?php
include_once('zq/db.php');
$sql = "select * from wd_sql";
$query=mysql_query($sql);
 $i = 1;
 while ($result = mysql_fetch_array($query)) {
 $x = $i++;
   "<br><a href='del.php?xx=".$result['id']."&ccxc=wd_sql'>删除</a>"//在这里实现了传值
}
?>


这个是接收值的php

 代码如下 复制代码

<?php
$uid = $_GET['xx'];
$db_sql = $_GET['ccxc'];
if(mysql_query($sql) == 1)
{echo "<script>alert('删除成功!');history.go(-1);</script>";}
?> 

php中更新数据中的记录使用update的sql语句,这个只要在php连接数据库之后执行sql语句即可,下面我们一起来看个例子。

sql有许多对数据库操作的语句。但是常见和比较需要的是这么几个语句 。UPDATE 语句用于在数据库表中修改数据。


UPDATE table_name  SET column1 = value1,column2 = value2 ...  WHERE column = some_value


例如,将user表中用户“张三”的密码修改为“ abc123 ”,年龄修改为“ 45 ”,SQL语句可以是这样:

UPDATE user SET password='abc123' , age='45'  WHERE  name='张三'

注意:UPDATE...SET...一般与WHERE子句一起使用,否则将修改数据表中的全部记录!

UPDATE 语句的例子

 代码如下 复制代码

<?php
$con = mysql_connect("localhost","peter","abc123");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }
mysql_select_db("my_db", $con);
mysql_query("UPDATE Persons SET Age = '36'
WHERE FirstName = 'Peter' AND LastName = 'Griffin'");
mysql_close($con);
?>

批量更新数据

 

 代码如下 复制代码

$sql="select * from booking_tables_info1";
  $query=$db->query($sql);
if($_POST['btnSave']){
   $checkbox = $_POST['range'];
/*如果要获取全部数值则使用下面代码*/
  for($i=0;$i<=count($checkbox);$i++)
   {
   if(!is_null($checkbox[$i]))
    {
     $chechvalue.=$checkbox[$i];
     $str="update booking_tables_info1 set ispass=1 where info_id=$chechvalue";
     $db->query($str);
    }
   }
   echo "<script>alert('更新成功!');window.location.href='http://blog.163.com/sun_jian_zhang/blog/memberManager.php';</script>";

}
?>

<html>
<head>
<meta http-equiv="Content-Language" content="en" />
<meta name="GENERATOR" content="PHPEclipse 1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>会员管理页面</title>
 <script type="text/javascript" language="javascript">
        function selectBox(selectType){
        var checkboxis = document.getElementsByName("range[]");
        if(selectType == "reverse"){
            for (var i=0; i<checkboxis.length; i++){
                //alert(checkboxis[i].checked);
                checkboxis[i].checked = !checkboxis[i].checked;
            }
        }
        else if(selectType == "all")
        {
            for (var i=0; i<checkboxis.length; i++){
                //alert(checkboxis[i].checked);
                checkboxis[i].checked = true;
            }
        }
     }
</script>
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#FF9966" vlink="#FF9966" alink="#FFCC99">
<form action="" method="post">
  <table border=1>
    <tr>
      <td>会员编号</td><td>卡型号</td><td>卡号< /td><td>名字</td><td>性别</td><td>年龄< /td><td>爸爸电话</td><td>妈妈电话</td><td>联系方 式</td><td>住址</td><td>宣言</td><td>是否通 过</td><td>参与时间</td><td><input type="button" value="全选" onclick="selectBox('all')"/><input type="button" value="反选" onclick="selectBox('reverse')"/></td>
    </tr>www.111cn.net
  <?php
      while($row=$db->fetch_array($query)){
      ?>
    <tr>
      <td><?php echo $row['info_id']?></td><td><?php echo $row['cardtype']?></td><td><?php echo $row['cardno']?></td> <td><?php echo $row['name']?></td><td><?php if($row['sex']==1){echo "男";}else{echo "女";}?></td><td><?php echo $row['age']?></td> <td><?php echo $row['fathermobile']?></td><td><?php echo $row['mothermobile']?></td><td><?php echo $row['tel']?></td> <td><?php echo $row['address']?></td><td><?php echo $row['enounce']?></td><td><?php echo $row['ispass']?></td><td><?php echo $row['jointime']?></td><td>
      <input type="checkbox" name="range[]" value="<?php echo $row['info_id'] ?>"/>


  </td>
    </tr>
      <?php
  }
    ?>
  </table>
<br>
<input type="submit" name="btnSave" value="批量审核通过"/>
</form>
</body>
</html>

注意在批量更新时要注意:<input type="checkbox" name="range[]" value="<?php echo $row['info_id'] ?>"/>中的name为range[]以数组形式。

sprintf与print 及printf都是输出字符串,但它们在细节中会有很大的区别,下面本文章就来重点介绍这个问题。

下面是一个示例:四舍五入保留小数点后两位

 代码如下 复制代码

<?php
$num1 = 21;
echo sprintf("%0.2f",$num1)."<br />"; //输出 21.00
$num2 = 16.3287;
echo sprintf("%0.2f",$num2)."<br />"; //输出 16.33
$num3 = 32.12329;
echo sprintf("%0.2f",$num3)."<br />"; //输出 32.12 www.111Cn.net
?>

解释下 %0.2f 的含义:

% 表示起始字符
0 表示空位用0填满
2 表示小数点后必须占两位
f 表示转换成浮点数


转换字符
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
% 印出百分比符号,不转换。
b 整数转成二进位。
c 整数转成对应的 ASCII 字元。
d 整数转成十进位。
f 倍精确度数字转成浮点数。
o 整数转成八进位。
s 整数转成字串。
x 整数转成小写十六进位。
X 整数转成大写十六进位。

printf与sprintf的区别

1. printf函数:

int printf ( string format [, mixed args [, mixed ...]] )

Produces output according to format , which is described in the documentation for sprintf() .

Returns the length of the outputted string.

 

把文字格式化以后输出,如:

 代码如下 复制代码
$name="hunte";
$age=25;
printf("my name is %s, age %d", $name, $age);

2. sprintf函数:
string sprintf ( string format [, mixed args [, mixed ...]] )

Returns a string produced according to the formatting string format .

 

跟printf相似,但不打印,而是返回格式化后的文字,其他的与printf一样。


3. print函数:

是函数,可以返回一个值,只能有一个参数。

int print ( string arg )

Outputs arg . Returns 1 , always.

 

[!--infotagslink--]

相关文章

  • Mysql常见问题集锦

    1,utf8_bin跟utf8_general_ci的区别 ci是 case insensitive, 即 "大小写不敏感", a 和 A 会在字符判断中会被当做一样的; bin 是二进制, a 和 A 会别区别对待. 例如你运行: SELECT * FROM table WHERE txt = 'a'...2013-10-04
  • go浮点数转字符串保留小数点后N位的完美解决方法

    这篇文章主要介绍了go浮点数转字符串保留小数点后N位解决办法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-05-11
  • PHP浮点数精度丢失问题解决方案

    浮点数就是有很我小数的那种并且不只单纯了数字了,而小编在用支付接口时就碰到浮点数丢失的问题,下文一起来看看问题解决方法. 先看下面这段代码: $f = 0.57; echo...2016-11-25
  • windows 10 安装和使用中5个常见问题

    2015年7月29日0点起,Windows 10推送全面开启,Windows7、Windows8.1用户可以免费升级到Windows 10,用户也可以通过系统升级到Windows10,在这过程中,用户会遇到这样那样的问题,下面小编总结了windows 10 安装和使用中5个常见问题,需要的朋友可以参考下...2016-01-27
  • php中session常见问题分析

    PHP的session功能,一直为许多的初学者为难。就连有些老手,有时都被搞得莫名其妙。本文,将这些问题,做一个简单的汇总,以便大家查阅。 1. 错误提示 引用 代...2016-11-25
  • 学习动态网页PHP技术常见问题汇总解答

    1:为什么我得不到变量 我在一网页向另一网页POST数据name,为什么输出$name时却得不到任何值? 在PHP4.2以后的版本中reGISter_global默认为off 若想取得从另一页...2016-11-25
  • 基于C++浮点数(float、double)类型数据比较与转换的详解

    本篇文章是对C++中浮点数(float、double)类型数据比较与转换进行了详细的分析介绍,需要的朋友参考下...2020-04-25
  • php FILTER_VALIDATE_FLOAT 浮点数验证

    filter_validate_float 过滤器把值作为浮点数来验证。 */ $var=12.3; var_dump(filter_var($var, filter_validate_float)); //float(12.3) /* 非负浮点数(正浮点数...2016-11-25
  • 浮点数在计算机中存储方式是怎样的

    这篇文章介绍了浮点数在计算机中是如何存储的,讲解的比较详细,有需要的朋友可以参考一下。...2020-04-25
  • 深入C++浮点数无效值定义与判定的解决办法

    本篇文章是对C++中浮点数无效值定义与判定进行了介绍,需要的朋友参考下...2020-04-25
  • Fatal error: Cannot redeclare 常见问题

    fatal error: cannot redeclare这种问题php教程 开发可能会碰到过,原因是很简单的,就是重复调用了相同名字的函数, function mydate($format='y-m-d h:i:s',$timest=0) {...2016-11-25
  • golang 比较浮点数的大小方式

    这篇文章主要介绍了golang 比较浮点数的大小方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-01
  • php中浮点数计算问题整理

    在php中浮点数计算通常我们会得不到自己想要的结果了,这个到底是什么原因呢,下面我们来分析问题的同时也给各位朋友整理了一些比较好用的实例。 如果用php的+-*/计...2016-11-25
  • round() 函数对浮点数进行四舍五入

    语法 round(x,prec)参数 描述 x 可选。规定要舍入的数字。 prec 可选。规定小数点后的位数。 说明 返回将 x 根据指定精度 prec (十进制小数点后数字的数目)进行四...2016-11-25
  • Python如何执行精确的浮点数运算

    这篇文章主要介绍了Python如何执行精确的浮点数运算,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-08-01
  • Php部分常见问题总结一

    Php部分常见问题总结-转载 1:为什么我得不到变量 我在一网页向另一网页POST数据name,为什么输出$name时却得不到任何值? 在PHP4.2以后的版本中register_global默...2016-11-25
  • Android内存泄露常见问题总结

    下面我们来看一篇关于Android内存泄露常见问题总结,希望这篇文章能够帮助到各位朋友,有兴趣的朋友可以进来看看吧. 在介绍内存泄漏之前很有必要提及一下Android...2016-11-01
  • 详解Xshell 常见问题及相关配置

    这篇文章主要介绍了详解Xshell 常见问题及相关配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-06
  • php中浮点数运算常见问题

    php中浮点数运算常见问题有哪些呢,今天我们就一起来看看这些关于php中浮点数运算常见问题总结吧,具体的如下文介绍. 本文实例分析了php中让人头疼的浮点数运算。...2016-11-25
  • C++数据精度问题(对浮点数保存指定位小数)

    这篇文章主要介绍了对浮点数保存指定位小数。比如, 1.123456. 要保存1位小数,,调用方法后, 保存的结果为: 1.1。 再比如,1.98765, 保存2位小数的结果为: 2.00,需要的朋友可以参考下...2020-04-25