Как эмулировать операции с плавающей запятой одинарной точности в PHP? - PullRequest
4 голосов
/ 15 ноября 2011

Мне нужно перенести простую программу на C на PHP.В настоящее время мы должны запустить процесс и проанализировать его вывод.Программа очень тривиальна, но для алгоритма важно использовать float, так как ошибки будут суммироваться, а результат будет далеко.

C пример:

#include <stdio.h>

int main( void ) {
  printf("%f\n", 123456 * (float)0.99524);
  printf("%f\n", 123456 * (double)0.99524);

  return 0;
}

PHPпример:

<?php

printf("%f\n", 123456 * 0.99524);

?>

Пример C приведёт к 122868.343750 и 122868.349440, в то время как PHP получит 122868.349440.

Как получить результат C floatв PHP?

Ответы [ 3 ]

2 голосов
/ 15 ноября 2011

Нет способа сделать это, используя встроенные функции php.

Тот, который использует "double", дает вам реальный результат, на 100% точный. Float один не так.

В PHP float и double имеют одинаковый тип, который является double.

Если вам нужны результаты высокой точности, которые всегда дают одинаковые результаты, попробуйте использовать модуль BC Math: http://php.net/bcmath

Пример кода с использованием BC Math:

$result = bcmul("123456", "0.99524", 6); // gives 122868.34944
$result = number_format($result, 6, ".", ""); // 122868.349440 - appending zeros
echo $result;

Выход:

122868.349440

Если вы действительно хотите получить тот же результат, что и в программе на C, тогда у вас есть 2 варианта:

  1. Создайте свою собственную c-like функцию, написав расширение php: http://www.google.com/search?q=writing+php+extensions

  2. Поговорите с C-программой из PHP через функцию proc_open (): http://www.php.net/manual/en/function.proc-open.php (см. Также popen (), exec () или shell_exec ())

0 голосов
/ 15 ноября 2011

Вы всегда можете создать модуль PHP.

Вот список ресурсов, которые я со временем собрал ...

http://www.delicious.com/homer6/php+extension

Кроме того, я очень рекомендую прочитать книгу Сары Големан:

http://blog.simonholywell.com/post/1156691738/15-excellent-resources-for-php-extension-development

Надеюсь, это поможет ...

0 голосов
/ 15 ноября 2011

Числа с плавающей точкой имеют ограниченную точность.Хотя это зависит от системы, PHP обычно использует формат двойной точности IEEE 754, который даст максимальную относительную ошибку из-за округления порядка 1.11e-16.Неэлементарные арифметические операции могут давать большие ошибки, и, конечно, при составлении нескольких операций необходимо учитывать программирование ошибок.

Кроме того, рациональные числа, которые точно представимы как числа с плавающей запятой в базе 10, например, 0,10.7, не имеют точного представления в виде чисел с плавающей точкой в ​​базе 2, которая используется внутри, независимо от размера мантиссы.Следовательно, они не могут быть преобразованы в их внутренние двоичные аналоги без небольшой потери точности.Это может привести к сбивающим с толку результатам: например, floor ((0.1 + 0.7) * 10) будет обычно возвращать 7 вместо ожидаемых 8, поскольку внутреннее представление будет примерно таким: 7.9999999999999991118 ....

Такникогда не доверяйте результатам с плавающей запятой последней цифре и никогда не сравнивайте числа с плавающей запятой на равенство.Если требуется более высокая точность, доступны математические функции произвольной точности и функции gmp.

В кавычках: http://php.net/manual/en/language.types.float.php

Чтобы изменить уровень точности PHP, измените precision настройки в php.ini

...