PHP - Сериализируйте плавающие точки

Наиболее вероятной причиной использования сингла по сравнению с дважды в различных библиотеках является предпочтение программиста и/или непротиворечивость API.

Кроме того, чтобы быть последовательным, используйте какой бы ни лучшие иски string:.

Используя другой тип кавычки как литерал:

alert('Say "Hello"');
alert("Say 'Hello'");

†¦, но это может получить complicated†¦

alert("It's \"game\" time.");
alert('It\'s "game" time.');

, Другая опция, новая в ES6, Шаблонные литералы , которые используют back-tick символ:

alert(`Use "double" and 'single' quotes in the same string`);
alert(`Escape the \` back-tick character and the \${ dollar-brace sequence in a string`);

Шаблонные литералы предлагают чистый синтаксис для: интерполяция переменной, многострочные строки, и т.д.

11
задан mskfisher 6 June 2012 в 13:36
поделиться

4 ответа

Число, подобное 6.2, не может быть точно представлено с помощью математики с плавающей запятой в компьютерах, поскольку для него нет конечного представления по основанию 2. То, что вы видите, когда echo -ing число предназначено для чтения человеком, и, таким образом, значение будет округлено до той, что может обеспечить точность с плавающей запятой (около 6 знаков после запятой для 32-битных и 17 для 64 -bit FP values).

Однако при сериализации этих значений вам действительно нужно точное значение (то есть все биты, которые там есть), а не только ближайшее «хорошее» значение. Может быть более одного представления float / double, которое оценивается примерно как 6,2, и при сериализации вы обычно действительно хотите сохранить точные значения до последнего имеющегося у вас бита, чтобы восстановить их правильно. Вот почему ты Повторяю смехотворную «точность» в значениях. Это просто для того, чтобы сохранить точное битовое представление того, с чего вы начали.

Но почему именно вы хотите так жестко контролировать сериализованный вывод? Я имею в виду, что это просто так, чтобы вы могли обойти свою структуру данных и прочитать ее позже. Вы, конечно, не хотите использовать это сериализованное представление где-то в выводе для людей или около того. Так что, если речь идет только о "красивых" значениях, не следует использовать сериализацию, которая имеет совершенно другую цель.

просто там, чтобы вы могли передать свою структуру данных и прочитать ее позже. Вы, конечно, не хотите использовать это сериализованное представление где-то в выводе для людей или около того. Так что, если речь идет только о "красивых" значениях, не следует использовать сериализацию, которая имеет совершенно другую цель.

просто там, чтобы вы могли передать свою структуру данных и прочитать ее позже. Вы, конечно, не хотите использовать это сериализованное представление где-то в выводе для людей или около того. Так что, если речь идет только о "красивых" значениях, не следует использовать сериализацию, которая имеет совершенно другую цель.

16
ответ дан 3 December 2019 в 01:53
поделиться

Сохраните их в виде строк после использования number_format :

$number = number_format($float, 2);
8
ответ дан 3 December 2019 в 01:53
поделиться

Сохраните их как целые числа (сдвиньте первый десятичный знак перед точкой, умножив его на 10) и преобразуйте их обратно, если вам это нужно:

function random_float($min,$max) {
    return ($min+lcg_value()*(abs($max-$min)));
}

$array = array();
for ($i=0; $i<10; $i++) {
    $array[] = (int) round(random_float(6, 8) * 10);
}
$serialized = serialize($array);
var_dump($serialize);

$array = unserialize($serialized);
foreach ($array as $key => $val) {
    $array[$key] = $val / 10;
}
var_dump($array);
3
ответ дан 3 December 2019 в 01:53
поделиться

Вот мой взгляд на ответ Гамбо. Я поместил туда IteratorAggregate, чтобы он был доступен для всех, но вы также можете добавить Countable и ArrayAccess.

<?php

class FloatStorage implements IteratorAggregate
{
  protected $factor;
  protected $store = array();

  public function __construct( array $data, $factor=10 )
  {
    $this->factor = $factor;
    $this->store = $data;
  }

  public function __sleep()
  {
    array_walk( $this->store, array( $this, 'toSerialized' ) );
    return array( 'factor', 'store' );
  }

  public function __wakeup()
  {
    array_walk( $this->store, array( $this, 'fromSerialized' ) );
  }

  protected function toSerialized( &$num )
  {
    $num *= $this->factor;
  }

  protected function fromSerialized( &$num )
  {
    $num /= $this->factor;
  }

  public function getIterator()
  {
    return new ArrayIterator( $this->store );
  }
}

function random_float ($min,$max) {
   return ($min+lcg_value()*(abs($max-$min)));
}

$original = array();
for ( $i = 0; $i < 10; $i++ )
{
  $original[] = round( random_float( 6, 8 ), 1 );
}

$stored = new FloatStorage( $original );

$serialized = serialize( $stored );
$unserialized = unserialize( $serialized );

echo '<pre>';
print_r( $original );
print_r( $serialized );
print_r( $unserialized );
echo '</pre>';
1
ответ дан 3 December 2019 в 01:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: