I have done a deep reserach on this topic. But nothing is clear about this question. Can anyone help me out with this.
http://www.php.net/manual/en/language.types.float.php
Nothing is properly described this link prperly.
Yes it does.
From the PHP Manual..
The size of an integer is platform-dependent, although a maximum value
of about two billion is the usual value (that's 32 bits signed).
64-bit platforms usually have a maximum value of about 9E18. PHP does
not support unsigned integers. Integer size can be determined using
the constant PHP_INT_SIZE, and maximum value using the constant
PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.
Also..
If the float is beyond the boundaries of integer (usually +/- 2.15e+9
= 2^31 on 32-bit platforms and +/- 9.22e+18 = 2^63 on 64-bit platforms), the result is undefined, since the float doesn't have
enough precision to give an exact integer result. No warning, not even
a notice will be issued when this happens!
Exerpts from the inner links of PHP Manual to a 3rd Party site...
PHP is dynamically typed and will often convert implicitly between
strings and floating-point numbers (which are platform-dependant, but
typically IEEE 64 bit values). To force a value to floating-point,
evaluate it in a numerical context: $foo = 0 + "10.5";
But if you are looking to play around with floats and precisions you need to use the GMP functions.
Values stores inside https://github.com/php/php-src/blob/master/Zend/zend.h#L322
For float use double type. Size of float and double.
So, php support 64-bit ieee float.
Related
var_dump((float)'79.10') returns me 79.09999999999999. I've tried a million ways to try and round this value up to the original 79.10 as a float (number_format, round), and I can't find a way to do it.
Is there any way I can get a float value of 79.10 from the original string?
No, because 0.1 (and, by extension, 79.1) is not actually representable as a float (assuming IEEE-754 single or double precision encoding). 0.1 in that encoding has an infinitely recurring fractional part:
1001 1001 1001 1001 ...
You'll either have to leave it as a string or accept the fact that the encoding scheme does not have infinite precision and work around it.
An example of the latter is to only output the numbers to a certain precision, such as two decimal digits, and to make sure that (in-)equality comparisons use either absolute or relative deltas to compare numbers.
When you're adding numbers, it takes quite a few operations for the imprecision effects to become visible at the hundredths level. It's quicker when multiplying but still takes a while.
While paxdiablo is right and working with floats does not have infinite precision, I've discovered that it is indeed possible to represent 79.10 as a float by first adjusting PHP's precision setting:
ini_set('precision', 15);
After that, var_dump((float)'79.10') correctly returns a float of 79.1. The different results that everyone is seeing on their own machines seems to be a result of everyone having different precision values set by default.
This is impossible as a float because it does not offer enough precision (see here for more information)
Now, in most languages you could cast it to a double... Unfortunately, in PHP, float and double use exactly the same underlying datatype so in order to get the value you want, you would have to recompile PHP.
Your best option would be to use something like the PHP BCMath module for arbitrary precision.
This question already has answers here:
Unexpected results when working with very big integers on interpreted languages
(36 answers)
Working with large numbers in PHP
(8 answers)
Closed 9 years ago.
using php, this code echo sprintf('%.9F',pow(3,47)); outputs 26588814358957501972480.000000000
where as other sites like this gives 3^47 = 26588814358957503287787. Is there any bug with PHP? How to resolve it?
btw, i'd like to know what is the maximum digit php can handle for calculation using pow,sprintf,fmod. Is it 300 digits?
You need to use an external program or a PHP extension (library).
I've just tested it with BC Math and GMP using the bcpow()/gmp_pow() functions and it works perfectly:
<?php
// both output 26588814358957503287787
echo bcpow('3', '47');
echo gmp_strval( gmp_pow('3', '47') );
The PHP.net documentation has a nice section about that topic:
Floating point precision
Floating point numbers have limited precision. Although it depends on
the system, PHP typically uses the IEEE 754 double precision format,
which will give a maximum relative error due to rounding in the order
of 1.11e-16. Non elementary arithmetic operations may give larger
errors, and, of course, error propagation must be considered when
several operations are compounded.
Additionally, rational numbers that are exactly representable as
floating point numbers in base 10, like 0.1 or 0.7, do not have an
exact representation as floating point numbers in base 2, which is
used internally, no matter the size of the mantissa. Hence, they
cannot be converted into their internal binary counterparts without a
small loss of precision. This can lead to confusing results: for
example, floor((0.1+0.7)*10) will usually return 7 instead of the
expected 8, since the internal representation will be something like
7.9999999999999991118....
So never trust floating number results to the last digit, and do not
compare floating point numbers directly for equality. If higher
precision is necessary, the arbitrary precision math functions and gmp
functions are available.
For a "simple" explanation, see the » floating point guide that's also
titled "Why don’t my numbers add up?"
— http://php.net/manual/en/language.types.float.php
Note that the php.ini configuration value 'precision' can also modify the precision when converting from floats to strings.
bcpow() (a function of the BCMath Arbitrary Precision Mathematics library) can be used in this case.
echo bcpow('3', '47'); //as mentioned in ComFreek's answer
//outputs 26588814358957503287787
The reason why pow isn't work here is because pow() uses float, and there's a size limitation for float.
See this excerpt from the PHP Manual:
The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format)
In other words, the maximum possible size may vary -- i.e. (may be different for 32-bit, and 64-bit systems).
Hope that answers your question!
My Thrift service expects to receive a Long integer representing a timestamp in milliseconds, but coming from PHP, I know PHP thrift is supposed to automagically turn my PHP types into thrift types, but which PHP type does it expect for Long integers? I think my computer is 64-bit, but since I think that PHP integers' length is platform dependent, I don't really want to depend upon a platform-dependent length for my integers.
I am currently grabbing microtime() and multiplying by 1000, then converting to integer. Is this the "correct" way to work with PHP & thrift long ints?
You are right,
The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.
http://www.php.net/manual/en/language.types.integer.php
If you use microtime() you need not to divide it by 1000. Its float, you may want to multiply it by 1000.
You may use BC Math for calclulate it as numbers, using string types. I guess string are OK to communicate with any other thing.
In case of multiplying by 1000, you even not need BCMath. Just delete comma from string representation of microtime(true) (or space from microtime)
Maybe you should use id of string type as like twitter: https://dev.twitter.com/docs/twitter-ids-json-and-snowflake
Can someone explain to me if I should use bcpow() instead of pow() and why?
I understand that not all installations of php have bcmath enabled. So if I write an open source project, and want to have as few dependencies/requirements as possible, I would rather use pow() in my code.
But what are the downsides to using pow() over bcpow()?
bcpow() is a function of the BCMath Arbitrary Precision Mathematics library.
Quoting the introduction of it's manual :
For arbitrary precision mathematics
PHP offers the Binary Calculator which
supports numbers of any size and
precision, represented as strings.
On the other hand, pow() is limited to floats, which have a limited size (quoting) :
The size of a float is
platform-dependent, although a maximum
of ~1.8e308 with a precision of
roughly 14 decimal digits is a common
value (the 64 bit IEEE format)
Generally, you'll work with pow() and other float-based functions (which are probably faster, and are always enabled) ; but, if you need to handle very big number, you'll have to work with bcpow().
According to the manual the bc* functions are
[...] arbitrary precision mathematics PHP offers the Binary Calculator which supports numbers of any size and precision, represented as strings.
pow() is limited to the maximum supported numeric representation on the system it runs on.
bcpow is used for arbitrary precision values. As a third parameter you can specify a number of digits after coma.
When I print this number in php 137582392964679 I get this as the output 1.37582392965E+14
All I am doing is a simple
print 137582392964679;
Anyone know why it's doing this? It's as if it's converting to an exponential number automatically. Someone said it's because I'm on a 32 bit machine. If that's the case how can I get around this problem?
Thanks
Check the const PHP_INT_MAX. You're likely over the max, which is typically around 2 billion for a 32bit system.
The maximum number you can store in a signed integer on a 32-bit machine is 2147483647. You can store numbers larger than this in a float but you risk losing some precision.
If that's the case how can I get around this problem?
You probably want to use a big number library. Try GMP:
$sum = gmp_add("123456789012345", "76543210987655");
echo gmp_strval($sum) . "\n";
Result:
200000000000000
Another alternative you could use is BC Math.
If you don't need to do any calculations with these numbers, but just store tham correctly, then store them as strings rather than integers.
I am on a 64 bit machine and it does the same thing. You might want to try using: print number_format(137582392964679);
That number is too big to fit into a 32-bit integer, so yes, it is converting to a floating point type automatically. How to get around it depends on the requirements of your system. If you aren't going to do any arithmetic then just store it as a string. If precision isn't overly important then you could leave it as a float and format it using printf. If precision is important and you can upgrade to 64-bit that should fix it, if you can't upgrade and you need an integer then you could look into using the BC Math PHP extension.
The manual clearly says:
If PHP encounters a number beyond the
bounds of the integer type, it will
be interpreted as a float instead.
Also your number cannot be represented accurately because of inherent floating point limitations, hence it is being approximated.