返回

PHP整数转两位小数浮点数并比较的完美解决方案

php

PHP 中如何将整数转换为带两位小数的浮点数并进行比较

碰到个小问题,要把一个整数(比如 $i = 50)变成带两位小数的浮点数( $m = 50.00 ),并且要让它俩用 == 比较的时候结果是 TRUE。 我试过 (float)$i,但没啥用。 抓耳挠腮了! 让我们来看看是啥情况, 怎么整。

一、 问题原因

PHP 是一种弱类型语言。 这也代表在做 $i == $m 的时候, PHP会做隐式转换,如果值相等, 会判断 true, 而不会校验两个值的类型是否一致。而 === 是校验的。 这带来便捷的同时,有时候,我们也遇到要确定类型和数值展示格式一致。

我们拆开看看这个问题。

  1. 类型转换(float) 这种方式确实可以把整数转换成浮点数。 比如$i=50, 经过(float)$i 会变成50.0, 但不一定是 50.00。PHP在做强制转换时候不会强制给你指定位数。
  2. 显示格式 : 默认情况下,PHP 显示浮点数时会尽可能简洁,所以 50.0 就直接显示成 50,不会带多余的 0
  3. 比较操作 : 针对题主的提问补充: "需要让 $i == $m 结果是 TRUE", 这点不用太担心。 PHP 的 == 运算符会先尝试进行类型转换,然后再比较值。

二、 解决方法

搞清楚了问题出在哪, 就好对症下药了, 解决这个有多种路子:

1. 使用 number_format() 函数 (主要针对显示)

number_format() 是 PHP 中专门用来格式化数字的函数, 可以指定小数位数、千位分隔符等等。

  • 原理: 这个函数会把数字转换成字符串,同时按照你的要求格式化。

  • 代码示例:

    $i = 50;
    $m = number_format($i, 2, '.', ''); // 第一个参数是要格式化的数字,第二个是小数位数,第三个是小数点符号,第四个是千位分隔符
    echo $m; // 输出 50.00
    
    //==比较时会转换$m类型。
    var_dump($i == $m); // bool(true)
    
    
  • 进阶技巧number_format() 的后面两个参数可以根据需要调整,比如做国际化展示的时候,不同国家的小数点和千位分隔符可能不一样。
    可以灵活配置,满足不同地区需要。

2. 使用 sprintf() 函数 (同样主要针对显示)

sprintf() 是一个更通用的格式化字符串的函数,也能用来格式化数字。

  • 原理: 它使用占位符来表示要插入的值,%.2f 就是一个占位符,表示保留两位小数的浮点数。

  • 代码示例:

    $i = 50;
    $m = sprintf("%.2f", $i);
    echo $m; // 输出 50.00
    
    //==比较时会转换$m类型。
     var_dump($i == $m); // bool(true)
    
  • 进阶技巧 : sprintf的能力很强大,格式化日期、字符串等等。 %.2f,其中f表示其类型是float, .2指明小数位数。 这是一个强大的工具函数。

3. 使用 round()函数(针对数值计算和比较)

如果除了显示之外, 还需要用这个带两位小数的浮点数进行计算, 并且精度很重要, 那可以用 round() 函数。

  • 原理: round() 函数会对数字进行四舍五入,可以指定保留的小数位数。

  • 代码示例:

    $i = 50;
    $m = round($i, 2); //$i 四舍五入到两位小数
    echo $m; // 输出 50  (注意,这里只是为了显示效果, round不处理格式, 所以只显示 50)
    
    $show = sprintf("%.2f", $m);
    echo $show; // 输出 50.00   
     //==比较时会转换$show类型。
     var_dump($i == $show); // bool(true)
    
    
  • 安全建议: 浮点数运算在计算机中可能会有精度损失。如果对精度要求极高,使用BCMath之类的函数,会提供更准确。

4. 直接进行比较 (利用松散比较的特性,适用于 $i == $mTRUE)

如果我们仅仅为了 $i == $m 返回 TRUE, 不需要真的做转换, PHP 的 == 运算符的特性,就能直接比较.

  • 原理 PHP是弱类型语言,使用==作比较的时候,会先做隐式转换, 不会检查变量的类型。

  • 代码示例 :

        $i = 50;
        $m = 50.00;
    
        var_dump($i == $m); // 输出 bool(true)
        var_dump($i === $m); //输出 bool(false)
    
    

    我们可以看到, $i == $m 符合题目条件, 比较的时候不需要做处理。

三、总结一下

如果仅作比较判断,直接用==即可满足需求。
如果要进行格式化显示, 且不影响计算精度, 使用number_format()sprintf()

如果既要格式化, 又要进行计算,还要考虑计算精度, 就结合 round()使用。 这样既能保证计算结果的准确性, 又能方便地进行格式化。
针对不同的实际需要来选择, 或者组合起来。