nan php что это

Точность чисел с плавающей точкой

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

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

«Простое» объяснение можно найти в » руководстве по числам с плавающей точкой, которое также называется «Why don’t my numbers add up?» («Почему мои числа не складываются?»)

Преобразование в число с плавающей точкой

Из строк

Если строка содержащая число или ведущая числовая, тогда она будет преобразована в соответствующее целочисленное значение, в противном случае она преобразуется в ноль ( 0 ).

Из других типов

Для значений других типов преобразование выполняется путём преобразования значения сначала в целое число ( int ), а затем в число с плавающей точкой ( float ). Смотрите Преобразование в целое число для получения дополнительной информации.

Поскольку определённые типы имеют неопределённое поведение при преобразовании в целое число ( int ), то же самое происходит и при преобразовании в число с плавающей точкой ( float ).

Сравнение чисел с плавающей точкой

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

Для сравнения чисел с плавающей точкой используется верхняя граница относительной ошибки при округлении. Эта величина называется машинной эпсилон или единицей округления (unit roundoff) и представляет собой самую маленькую допустимую разницу при расчётах.

= 1.23456789 ;
$b = 1.23456780 ;
$epsilon = 0.00001 ;

User Contributed Notes 36 notes

PHP thinks that 1.6 (coming from a difference) is not equal to 1.6. To make it work, use round()

var_dump(round($x, 2) == round($y, 2)); // this is true

While the author probably knows what they are talking about, this loss of precision has nothing to do with decimal notation, it has to do with representation as a floating-point binary in a finite register, such as while 0.8 terminates in decimal, it is the repeating 0.110011001100. in binary, which is truncated. 0.1 and 0.7 are also non-terminating in binary, so they are also truncated, and the sum of these truncated numbers does not add up to the truncated binary representation of 0.8 (which is why (floor)(0.8*10) yields a different, more intuitive, result). However, since 2 is a factor of 10, any number that terminates in binary also terminates in decimal.

I’d like to point out a «feature» of PHP’s floating point support that isn’t made clear anywhere here, and was driving me insane.

Will fail in some cases due to hidden precision (standard C problem, that PHP docs make no mention of, so I assumed they had gotten rid of it). I should point out that I originally thought this was an issue with the floats being stored as strings, so I forced them to be floats and they still didn’t get evaluated properly (probably 2 different problems there).

To fix, I had to do this horrible kludge (the equivelant of anyway):

if (round($a,3)>=round($b,3)) echo «blah!»;

THIS works. Obviously even though var_dump says the variables are identical, and they SHOULD BE identical (started at 0.01 and added 0.001 repeatedly), they’re not. There’s some hidden precision there that was making me tear my hair out. Perhaps this should be added to the documentation?

Concider the following:

19.6*100 cannot be compaired to anything without manually
casting it as something else first.

Rule of thumb, if it has a decimal point, use the BCMath functions.

The ‘floating point precision’ box in practice means:

This returns 0.1 and is the workaround we use.

So, that’s all lovely then.

In some cases you may want to get the maximum value for a float without getting «INF».

var_dump(1.8e308); will usually show: float(INF)

I wrote a tiny function that will iterate in order to find the biggest non-infinite float value. It comes with a configurable multiplicator and affine values so you can share more CPU to get a more accurate estimate.

I haven’t seen better values with more affine, but well, the possibility is here so if you really thing it’s worth the cpu time, just try to affine more.

Best results seems to be with mul=2/affine=1. You can play with the values and see what you get. The good thing is this method will work on any system.

Beware of NaN and strings in PHP.
In other languages (and specifically in Javascript) math operations with non-numerical strings will result in NaN, while in PHP the string is silently converted to 0.

is_nan(‘hello, string’); // false

gives the impression that the string is a valid number.

Be careful when using float values in strings that are used as code later, for example when generating JavaScript code or SQL statements. The float is actually formatted according to the browser’s locale setting, which means that «0.23» will result in «0,23». Imagine something like this:

This would result in a different result for users with some locales. On most systems, this would print:

but when for example a user from Germany arrives, it would be different:

which is obviously a different call to the function. JavaScript won’t state an error, additional arguments are discarded without notice, but the function doBar(a) would get 0 as parameter. Similar problems could arise anywhere else (SQL, any string used as code somewhere else). The problem persists, if you use the «.» operator instead of evaluating the variable in the string.

So if you REALLY need to be sure to have the string correctly formatted, use number_format() to do it!

To simply convert 32 bits float from hex to float:

To compare two numbers use:

In the gettype() manual, it says «(for historical reasons «double» is returned in case of a float, and not simply «float») «.

However, I think that internally PHP sometimes uses the C double definition (i.e. a double is twice the size of a float/real). See the example below:

(The strrev_x-bin2hex combination is just to give printable characters.)

Given that PHP treats doubles and floats identically, I’d expected the same string as output, however, the output is:

double pack
string(16) «3ff999999999999a» //Here you see that there is a minute difference.
string(16) «3ff9999999999998»
float pack
string(8) «3fcccccd» //. which doesn’t exist here
string(8) «3fcccccd»

Convert a hex string into a 32-bit IEEE 754 float number. This function is 2 times faster then the below hex to 32bit function. This function only changes datatypes (string to int) once. Also, this function is a port from the hex to 64bit function from below.

But, please don’t use your own «functions» to «convert» from float to binary and vice versa. Looping performance in PHP is horrible. Using pack/unpack you use processor’s encoding, which is always correct. In C++ you can access the same 32/64 data as either float/double or 32/64 bit integer. No «conversions».

PHP switches from the standard decimal notation to exponential notation for certain «special» floats. You can see a partial list of such «special» values with this:

I have to be honest: this is one of the strangest things I have seen in any language in over 20 years of coding, and it is a colossal pain to work around.

Just another note about the locales. Consider the following code:

convert 32bit HEX values into IEEE 754 floating point
= «C45F82ED» ;

I’ve just come across this issue with floats when writing a function for pricing. When converting from string to a float, with 2 digits of precision, the issue with comparing floats can pop up and give inconsistent results due to the conversion process.

An easier way rather than relying on the mentioned epsilon method is to use number_format (at least for me as I’ll remember it!).

Example function that can return an unexpected result:

if((float)$a == (float)$b) <
echo true;
> else <
echo false;
>

echo’s false in this example.

Using number format here to trim down the precision (2 point precision being mostly used for currencies etc, although higher precisions should be correctly catered for by number_format), will return an expected result:

if(number_format((float)$a, 2) == number_format((float)$b, 2)) <
echo true;
> else <
echo false;
>

Correctly echo’s true.

My BIN to FLOAT (IEEE754), the first one doesn’t work for me:

As «m dot lebkowski+php at gmail dot com» (http://www.php.net/language.types.float#81416) noted 9 comments below :

When PHP converts a float to a string, the decimal separator used depends on the current locale conventions.

Calculations involving float types become inaccurate when it deals with numbers with more than approximately 8 digits long where ever the decimal point is. This is because of how 32bit floats are commonly stored in memory. This means if you rely on float types while working with tiny fractions or large numbers, your calculations can end up between tiny fractions to several trillion off.

Источник

is_nan

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

is_nan — Проверяет, является ли значение «не числом»

Описание

Список параметров

Возвращаемые значения

Примеры

Пример #1 Пример использования is_nan()

// Недопустимое вычисление, возвращает
// значение «не число» (NaN)
$nan = acos ( 8 );

Результат выполнения данного примера:

Смотрите также

User Contributed Notes 7 notes

nan/»not a number» is not meant to see if the data type is numeric/textual/etc..

NaN is actually a set of values which can be stored in floating-point variables, but dont actually evaluate to a proper floating point number.

The floating point system has three sections: 1 bit for the sign (+/-), an 8 bit exponent, and a 23 bit fractional part.
There are rules governing which combinations of values can be placed into each section, and some values are reserved for numbers such as infinity. This leads to certain combinations being invalid, or in other words, not a number.

I would use is_numeric() instead of ctype_digit() if you cannot be 100% sure what data type the string will be. Example from the docs:

Starting with PHP 7, the string ‘NaN’ evaluates to the NaN value as well.

Example:
var_dump( (float) ‘NaN’ );

PHP 5.x and HHVM:
float(0)

It seems odd to me, but in boolean context, NAN evalutes to true.

( acos ( 8 ));
var_dump ((bool) acos ( 8 ));
?>

Returns:

I have decided to do some testing because I am getting unusual results with the is_nan function and here are the results of my tests:

var_dump ( NAN == NAN ); // boolean true
var_dump ( NAN === NAN ); // boolean true
var_dump ( is_nan ( NAN )); // boolean true

var_dump ( NAN == 12 ); // boolean true
var_dump ( NAN === 12 ); // boolean false
var_dump ( is_nan ( 12 )); // boolean false

var_dump ( NAN == 12.4 ); // boolean true
var_dump ( NAN === 12.4 ); // boolean true
var_dump ( is_nan ( 12.4 )); // boolean false

var_dump ( NAN == NULL ); // boolean true
var_dump ( NAN === NULL ); // boolean false
var_dump ( is_nan ( NULL )); // boolean false

Источник

NaN все еще может немного удивить

nan php что это. Смотреть фото nan php что это. Смотреть картинку nan php что это. Картинка про nan php что это. Фото nan php что это

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

Ответ должен быть NaN. Но почему я не уверен в этом? Всю дорогу была уверенность в том, что любые выражения, содержащие NaN, вернут NaN. Ну разве что только если поделить NaN на ноль — в этом случае будет вызвано исключение ZeroDivisionError. Сто процентов NaN!

Ввожу выражение в ячейку блокнота:

В самом деле? Постойте:

То есть, по какой-то причине, единица в степени NaN — это единица, а вот ноль и все остальные числа в степени NaN — это NaN. Где логика? В чем дело?

Так, давайте еще раз:

Может быть я просто из-за отсутствия какой-то практической надобности в глубоких познаниях о NaN, просто о чем-то не подозревал? А может я знал, но забыл? А может еще хуже — я не знал и забыл?

Заходим на Википедию. Там данный вопрос тоже обозначен как проблема, но почему все именно так устроено, никак не объясняется. Зато узнал что:

Хотя, в то же время:

Что, согласитесь, тоже немного странно.

Ладно, с Википедии отправляемся в C99 на 182 страницу и наконец-то получаем логическое объяснение, почему pow(x, 0) возвращает 1 для любых x, даже для x равного NaN:

Если функция nan php что это. Смотреть фото nan php что это. Смотреть картинку nan php что это. Картинка про nan php что это. Фото nan php что этовозводится в степень nan php что это. Смотреть фото nan php что это. Смотреть картинку nan php что это. Картинка про nan php что это. Фото nan php что этои при этом nan php что это. Смотреть фото nan php что это. Смотреть картинку nan php что это. Картинка про nan php что это. Фото nan php что этостремится к 0, то в результате получится 1, вне зависимости от того, какое значение имеет nan php что это. Смотреть фото nan php что это. Смотреть картинку nan php что это. Картинка про nan php что это. Фото nan php что это.

nan php что это. Смотреть фото nan php что это. Смотреть картинку nan php что это. Картинка про nan php что это. Фото nan php что это

А если результат не зависит от числового значения функции nan php что это. Смотреть фото nan php что это. Смотреть картинку nan php что это. Картинка про nan php что это. Фото nan php что это, то 1 — является подходящим результатом, даже для NaN. Однако это по-прежнему не объясняет, почему 1 в степени NaN равна 1.

Отыскиваем еще один C99 и на 461 странице не видим никаких объяснений, просто требование того, что pow(+1, y) должно возвращать 1 для всех y, даже равных NaN. Все.

С другой стороны, объяснение, почему pow(NaN, 0)=1 является более предпочтительным, чем pow(NaN, 0)=NaN все-таки наталкивает на мысль о том, что NaN не стоит воспринимать буквально, как Not-a-Number. Допустим, в результате каких- то вычислений мы получили число, превышающее размер памяти, выделенный под данный тип чисел, например:

В результате мы получили inf, что именно это за число мы не знаем, но все же это какое-то число. Затем мы снова что-то вычислили и снова получили слишком большое число:

Разность a и b вернет NaN:

Единственная причина, по которой мы можем считать c не числом, заключается в том, что мы использовали недостаточно точные вычисления. Однако, в c под NaN все же скрывается какое-то значение. О том, что это за значение, мы не знаем. Но все же это число, а раз это число, то нет ничего удивительного в том, что pow(1, NaN)=1.

Почему же тогда pow(0, NaN)=NaN? Дело в том, что если возвести 0 в любую степень, то мы действительно получим ноль. Кроме одного единственного случая — когда степень равна 0:

Из-за чего в выражении pow(0, NaN) появляется неопределенность с конкретным значением NaN. Конечно, вероятность того, что под NaN может скрываться 0 — исчезающе мала и можно было бы принять, что pow(0, NaN)=0. Но все же лучше перестраховаться, мало ли к чему это может привести. Возможно, так и рассуждали, когда создавались стандарты.

Даже не знаю, что еще сказать… если вы заранее знали ответ, то скорее всего вам можно позавидовать, ведь сферы, где могут пригодиться такие познания, наверняка, переполнены интересными задачами. А может и наоборот. Напишите об этом в комментариях.

P.S. Поскольку NaN относится к числам с плавающей точкой, оно может быть ключом словаря:

Имеет ли смысл использовать такое на практике? Думаю, что лучше не стоит.

Источник

PHP целые числа, числа с плавающей точкой и числовые строки

Работа с числами на PHP кажется тривиальной концепцией, но она может быть довольно запутанной. Сначала это выглядит легко, потому что PHP обеспечивает автоматическое преобразование типов. Например, вы можете назначить целочисленное значение переменной, и тип этой переменной будет целым числом. На следующей строке вы можете назначить строку той же переменной и тип изменится на строку. К сожалению, это автоматическое преобразование может иногда нарушать ваш код.

Существует множество типов для числовых значений. В этом уроке вы узнаете о целых числах и числах с плавающей точкой в PHP, а также о функциях, которые могут использоваться для определения типа чисел, с которыми мы имеем дело, и преобразования между ними. Вы также узнаете, как преобразовать целые числа и числа с плавающей точкой в числовые строки и из них.

Различные типы чисел в PHP

Целые числа

Числа с плавающей точкой

Бесконечность и NaN

Есть еще два вида числовых значений, с которыми вам придется иметь дело при написании программ, связанных с математикой. Эти значения бесконечности и NaN (не числа). Оба эти значения требуют небольшого объяснения, потому что они отличаются от ожидаемых.

Численные строки в PHP

Подобно тому, как PHP динамически меняет тип разных чисел в зависимости от того, как их значения используются или назначаются, он также может вывести значение различных числовых строк для преобразования их в числа.

PHP будет неявно использовать любую действительную числовую строку для числа, когда возникнет необходимость. Следующие примеры помогут вам лучше понять этот процесс.

В последнем случае шестнадцатеричная строка «0xfedd24» не преобразуется в ее десятичное значение, потому что PHP 7 не считает ее допустимой числовой строкой.

Приведение строк и чисел с плавающей точкой к целым числам

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

Заключительные мысли

После прочтения этого урока вы сможете определить тип числа или конечный тип результата после использования различных операций с использованием предопределенных функций, а также явно передать их определенному типу после выполнения некоторых проверок.

Как всегда, если у вас есть какие-либо вопросы или дополнительные советы, вы можете оставить комментарий.

Источник

Различные типы чисел в PHP

Работая с числамт следует отметить, что PHP обеспечивает автоматическое преобразование типов данных. Например, если вы присвоите переменной целочисленное значение, тип этой переменной автоматически будет целым числом. На следующей строке кода вы можете назначить строку той же переменной и её тип изменится на строку. Это автоматическое преобразование иногда может нарушить ваш код.

Целые числа PHP

Основные правила определения целого числа:

Функции PHP для проверки целочисленного типа переменной:

Проверим, является ли тип переменной целым числом:

Пример

Результат выполнения кода:

Число с плавающей точкой

В PHP есть следующие функции для проверки того, является ли переменная типом float :

Пример

Результат выполнения кода:

PHP Бесконечность

В PHP любое числовое значение выше PHP_FLOAT_MAX на платформе считается бесконечным.

Функция PHP var_dump() возвращает тип данных и значение:

Пример

Результат выполнения кода:

Специальное значение NAN

Функция PHP var_dump() возвращает тип данных и значение:

Пример

Результат выполнения кода:

Числовые строки в PHP

PHP будет неявно использовать любую действительную числовую строку для числа, когда возникнет необходимость. Следующие примеры помогут вам лучше понять этот процесс:

Пример

Результат выполнения кода:

В предпоследнем случае шестнадцатеричная строка «0xfedd24» не преобразуется в ее десятичное значение потому, что PHP 7 не считает ее допустимой числовой строкой.

Примечание: Примечание: Начиная с PHP 7.0 функция is_numeric() возвращает значение FALSE для числовых строк в шестнадцатеричной форме (например, «0xfedd24» ), поскольку они больше не считаются числовыми строками.

Приведение строк и чисел с плавающей точкой к целым числам

Иногда вам будет нужно преобразовать числовое значение в другой тип данных. В PHP имеется множество функций и методов для этих целей. В большинстве случаев приведение будет выполнено неявно и вам не придется беспокоиться об этом. Но, если вам нужно сделать преобразование, используйте методы, приведенные ниже.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *