首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在PHP中获取浮点数的二进制表示?

如何在PHP中获取浮点数的二进制表示?
EN

Stack Overflow用户
提问于 2011-01-19 05:59:24
回答 4查看 5.2K关注 0票数 10

有没有办法在PHP中获得浮点数的二进制表示?类似于Java的Double.doubleToRawLongBits()

给定一个正的浮点数,我想得到最大的可表示的浮点数,它小于这个数字。在Java中,我可以这样做:

代码语言:javascript
复制
double x = Double.longBitsToDouble(Double.doubleToRawLongBits(d) - 1);

但我在PHP中看不到类似的东西。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-01-19 06:15:02

这不是一个完整的答案,但我所知道的将浮点数转换为二进制的唯一方法是使用pack()

票数 2
EN

Stack Overflow用户

发布于 2011-01-19 22:17:42

这是我根据Peter Bailey的建议想出的一个解决方案。它需要64位版本的PHP。我不是说这是产品级的,但我在此分享,以防有人想要在它的基础上构建。(事实上,在我发布这个问题后,我做了一些完全不同的事情,但我把它留在这里作为一个智力练习)。

代码语言:javascript
复制
// Returns the largest double-precision floating-point number which
// is less than the given value. Only works for positive values.
// Requires integers to be represented internally with 64 bits (on Linux
// this usually means you're on 64-bit OS with PHP built for 64-bit OS).
// Also requires 64-bit double-precision floating point numbers, but I
// think this is the case pretty much everywhere.
// Returns false on error.
function prevDouble($d) {
  $INT32_MASK = 0xffffffff;
  if((0x1deadbeef >> 32) !== 1) {
    echo 'error: only works on 64-bit systems!';
    return false;
  }
  if($d <= 0) {
    return false;
  }
  $beTest = bin2hex(pack('d', 1.0)); //test for big-endian
  if(strlen($beTest) != 16) {
    echo 'error: system does not use 8 bytes for double precision!';
    return false;
  }

  if($beTest == '3ff0000000000000') {
    $isBE = true;
  }
  else if($beTest == '000000000000f03f') {
    $isBE = false;
  }
  else {
    echo 'error: could not determine endian mode!';
    return false;
  }

  $bin = pack('d', $d);

  //convert to 64-bit int
  $int = 0;
  for($i = 0; $i < 8; $i++)
    $int = ($int << 8) | ord($bin[$isBE ? $i : 7 - $i]);

  $int--;
  //convert back to double
  if($isBE)
    $out = unpack('d', pack('N', ($int >> 32) & $INT32_MASK) . pack('N', $int & $INT32_MASK));
  else
    $out = unpack('d', pack('V', $int & $INT32_MASK) . pack('V', ($int >> 32) & $INT32_MASK));

  return $out[1];
}
票数 6
EN

Stack Overflow用户

发布于 2013-01-04 04:37:58

作为对整个问题的补充回答,而是对标题的补充:

如果你想看看你的浮点数看起来像是二进制的:

代码语言:javascript
复制
function floatToBinStr($value) {
   $bin = '';
    $packed = pack('d', $value); // use 'f' for 32 bit
    foreach(str_split(strrev($packed)) as $char) {
        $bin .= str_pad(decbin(ord($char)), 8, 0, STR_PAD_LEFT);
    }
    return $bin;
}

echo floatToBinStr(0.0000000000000000000000000000000000025).PHP_EOL;
echo floatToBinStr(0.25).PHP_EOL;
echo floatToBinStr(0.5).PHP_EOL;
echo floatToBinStr(-0.5).PHP_EOL;

输出:

代码语言:javascript
复制
0011100010001010100101011010010110110111111110000111101000001111
0011111111010000000000000000000000000000000000000000000000000000
0011111111100000000000000000000000000000000000000000000000000000
1011111111100000000000000000000000000000000000000000000000000000
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4729526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档