【问题标题】:PHP Leftmost digitPHP 最左边的数字
【发布时间】:2011-03-11 22:08:21
【问题描述】:

假设我有一个包含整数或浮点数的变量(因为整数可能会溢出到 PHP 中的浮点数)。

我想运行一些操作来获取最左边的数字和其余的数字。

为了更好地解释:

<?php

$x   = NULL;  //this will hold first digit
$num = 12345; //int

/// run operation


//outputs
//$x   = 1;
//$num = 2345;
var_dump($x, $num);

?>

现在,如果您将数字表示为字符串,我知道有多种方法可以做到这一点,但我试图避免将其类型转换为字符串。

我可能正在寻找包含按位运算的解决方案,但我在该主题上相当薄弱,所以我希望通常在低级工作的人能够回答这个问题!

非常感谢。

【问题讨论】:

  • 该任务的目的肯定会有所帮助。
  • 您正在寻找的是整数除法和模运算符。
  • @Col。弹片:证明有点复杂,但简单地说,我想从左到右循环每个数字。 @Ranieri:我去看看,谢谢。

标签: php digits


【解决方案1】:

我确信有一种方法可以做到这一点,而无需将其转换为字符串,但为什么呢? string 绕道就是这么简单:

$x = (int)substr($num, 0, 1); 

它会给你一个很好的、正确的整数。

显然,这不会对错误输入进行扩展检查,并且要求$num 是一个有效数字。

【讨论】:

  • PHP 手册:也可以使用大括号访问字符串,如 $str{42},用于相同目的。但是,从 PHP 5.3.0 开始不推荐使用此语法。请改用方括号,例如 $str[42]。
  • 对于 -ve num,十进制数,您的解决方案将不起作用。见stackoverflow.com/a/7413381/2736817
【解决方案2】:

获取其余数字

$remainingnum = (int)substr((string)$num, 1, strlen($num));

【讨论】:

    【解决方案3】:

    如果您将值类型转换为字符串,则可以使用数组类型选择器。

    例如:

    $n = (string)12345676543.876543;
    echo (int)$n[0];
    

    【讨论】:

      【解决方案4】:

      避免使用任何字符串操作,但不保证浮点甚至负值

      $x   = NULL;  //this will hold first digit
      $num = 12345; //int
      
      $m = 1;
      while(true) {
          $m *= 10;
          if ($m > $num)
              break;
      }
      
      $m /= 10;
      
      $x = (int) floor($num / $m);
      $num = $num % $m;
      
      
      //outputs
      //$x   = 1;
      //$num = 2345;
      var_dump($x, $num);
      

      【讨论】:

      • 如果你也想使用 float,那么你需要替换 $num = $num % $m; $num = fmod($num,$m);
      • 我不明白为什么将字符串转换为字符串并返回是不可能的,但是 +1 可以满足 OP 的要求。
      • 我想对数学解决方案/字符串操作之间的差异进行基准测试。我知道,优化是万恶之源,但我正在处理数以千计的数字,所以我有一些额外的时间可以闲逛。
      • 我敢打赌字符串操作会更快,但您可能希望在运行任何性能测试之前先对 while 循环进行微优化,因为这不是特别有效
      • 根据我自己的测试:return floor($num/pow(10,(floor((log10($num)))))); 需要 0.000005 秒,return (int)substr($num, 0, 1); 需要 0.000004 秒。数字的大小不会显示处理时间的任何变化。
      【解决方案5】:

      @Mark Ba​​ker 提供了最好的解决方案,但您应该在应用算法之前先执行abs(floor($num))

      【讨论】:

        【解决方案6】:

        纯数学方法:

        function leftMost($num) {  
            return floor($num/pow(10,(floor((log10($num))))));
        }
        

        解释我猜...

        num 的 1+ log10 计算数字的位数,我们将其取底以删除任何十进制值,将其作为指数,因此对于 1 位数字,我们得到 10^0=1 或 8 位数字我们得到 10^8。然后我们只是将 12345678/10000000 = 1.2345678 相除,得到 floor'd 并且只有 1。

        注意:这也适用于 0 和 1 之间的数字,它将返回 0.02 中的 2,并且字符串转换将失败。

        如果要处理负数,请先使 $num = abs($num)。

        【讨论】:

        • 我从$num = 12345得到结果881。
        • 对不起,我用 10^ 代替了 pow()。
        • 这不适用于负数或 0。您应该使用 abs($num) 来保证它是正数,并为 0 的特殊情况返回 0。或者,如果 $ num
        • @adamnfish 我在我的一次编辑中提到了这一点。此外,零是有史以来最糟糕的数字。整天。 -- 对 0 不起作用的原因,因为 log10(0) 处于负无穷大。
        • 您的解决方案很棒,尽管正确的答案必须交给马克贝克,因为他还展示了如何获得剩余的数字。也就是说,非常感谢您的解决方案!
        【解决方案7】:

        我知道你说过你想避免转换为字符串,但如果你想在 PHP 中循环数字,这将是最快的方法:

        $len = strlen($n);
        for ($i = 0; $i < $len; ++$i)
          $d = $n[$i];
        

        在快速而简单的基准测试中,它比等效的数学表达式集快约 50%,即使在最小化对 logexp 的调用时也是如此。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-13
          • 2021-10-04
          相关资源
          最近更新 更多