【问题标题】:Convert a full string (represented in exponential format) back in number in PHP在 PHP 中将完整的字符串(以指数格式表示)转换回数字
【发布时间】:2018-08-01 04:27:29
【问题描述】:

我一直在寻找将我的指数数字字符串转换为精确数字的方法。 所以,我有一个指数数字存储在 MySQL 中的字符串。我想以确切的数字转换回这个字符串。 但似乎这个数字很大,而且越界了,给我提供了错误的数据。

虽然我尝试了各种格式的代码,但结果格式不正确。

policy_number = "2.9992020830803E+18";  
number_format($policy_number, 0,'.','');  
// Output  
 2999202083080300032  


(float) $policy_number;  
// Output
2.9992020830803E+18  


sscanf($policy_number, "%f")[0];  
// Output
2.9992020830803E+18  


floatval($policy_number);   
// Output
2.9992020830803E+18  


gmp_init("2.9992020830803E+18");  
gmp_strval($policy_number);  
// Output
0  


"2.9992020830803E+18" + 0;  
// Output
2.9992020830803E+18  

请告诉我转换它的正确方法。

【问题讨论】:

  • 那么,您究竟试图得到什么作为输出?如果你将一个大整数存储为一个数字,而它应该是一个字符串——我猜你这样做了,基于变量名——你不能可靠地“转换回”为整数.当您以数字格式存储信息时,您会丢失信息。
  • 我试图获得 2999202083080300000。如果您在我的第一次尝试中看到它给出了额外的 32,不知道为什么?
  • 如果您总是希望数字以零结尾,那么将其转换为字符串是微不足道的。但是,正如我已经建议的那样,这里真正的解决方案是将数据存储为字符串,而不是数字。毕竟,如果这是一个标识符号,您对 amount 不感兴趣;你对特定的数字串感兴趣。您应该相应地存储数据。
  • 感谢您的回复。我在这里有点困惑。看,我已经将这个 policy_number 存储在 MySQl 中,它是一个 Varchar。 (我无法将其更改为任何其他数据类型,因为它可能在保单编号中也有 char)。现在我正在尝试从 Mysql 中检索它并希望在 HTML 上展示。由于数字在 MYSQL 中已经是指数格式,我尝试使用 number_format 函数进行转换。当我使用 PHP 时,相信它会关心数据类型本身。就 MySQL 而言,我无法更改值输入,因为它已经是指数格式。
  • Varchar 是一种合理的列数据类型。您的问题似乎是您在保存到数据库或检索它时不小心将其转换为数值。不可能说是哪个,因为你没有提供任何代码。无论如何,这是XY problem 的明显实例;您必须解决的真正问题不是将指数符号中的数字转换为简单的整数,而是首先避免将数据放入该格式。

标签: php string numbers exponential


【解决方案1】:

更新

我同意 Ed Cottrell 的观点,即您的问题是如何将数据存储在数据库中。但是,如果这是一个项目,您已经在查看已经存储为指数的大量数据,那么我编写的这个函数应该适合您。它应该适用于正负基数和指数。它基本上模仿了您手动操作的方式。

我无法找到使用数学函数的方法。如果有人知道如何做得更好,请发布。与此同时,我写这篇文章很开心。

希望对你有所帮助!

function getRealNumber($number){

  //Parse the base and exponent.
  preg_match('/^(.*?)E[\-|\+](.*?)$/', $number, $data);

  $base = $data[1];
  $exp = $data[2];

  //Test to see if the base is negative.
  if(preg_match('/\-/', $base)){

    $base = str_replace('-', '', $base);
    $isNegative = TRUE;

  }

  //Capture the offset of the decimal point.
  preg_match('/\./', $base, $position, PREG_OFFSET_CAPTURE);

  $offset = $position[0][1]; //This is the offset of the decimal point.
  $string = str_replace('.', '', $base); //Get numbers without decimal.
  $length = strlen($string); //Get the length of string.

  //Test to see if we are adding zeros to the end or beginning of string.
  if(preg_match('/E\+/', $number)){

    //Let's move the decimal.
    if($length > ($exp + $offset)){

      $string = substr_replace($string, '.', ($exp + $offset), 0);

    } else {

      $string = $string . str_repeat('0', $exp - ($length - $offset));

    }


  }elseif(preg_match('/E\-/', $number)){

    //Calculate the number of zeros needed to add and append them.
    if($offset > $exp){

      $string = substr_replace($string, '.', $offset, 0);

    } else {

      $string = '0.' . str_repeat('0', $exp - $offset) . $string;

    }

  }

  //Add the negative sign if we need to.
  if(!$isNegative){

    return $string;

  } else {

    return '-' . $string;

  }

}

$policy_number = "2.9992020830803E+18";
echo getRealNumber($policy_number);

//Will output 2999202083080300000

【讨论】:

  • 看看你是否尝试将 2.9992020830803E+18 转换为数字,它应该是 2999202083080300000,而输出是 2999202083080300032。这就是我苦苦挣扎的地方。
  • if(!$isNegative) 应该是if(!isset($isNegative))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-05
相关资源
最近更新 更多