why pow(3^47) gives wrong answer? [duplicate] - php

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!

Related

Laravel issue when printing a double field coming from the database

I have an issue with laravel or php (don´t know yet), the issue is the next:
I have a field on my database called debe which value is 3.97 as you can see below. This field is a double(11,2).
When I access to that field on my framework, for example using a dd() it returns the value correctly as you can see below.
The main problem occurs when i'm trying to print into the view, I receive the next:
I dont know why this is happening but right now the only solution that I've found is to round the value using PHP round() function.
Regards
Check this article in the official documentation:
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.
You can use the round or number_format functions to get the desired decimals

PHP calculating with negative numbers gives wrong values

My PHP code:
echo -100.35+100.00;
echo '<br/>';
echo -478.35+478.32+0.03;
Gives output:
-0.34999999999999
-2.9559688030645E-14
I don't understand why, i tried (float) in front of the values but no difference.
You should use BC Math Functions for such calculations.
Take a look at this manual, it explains that the internal representation is not 100% exact for floats... it has to do with the internal representation of the floats I suspect.
The manual does also refer to these methods and also these for calculations with need of precision.
This is how floats work. In PHP, there are integers, or there are floats - no exact decimals or the like.
Floats are simply not EXACT - there isn't too much you can do about it. http://www.php.net/manual/en/language.types.float.php
Note the big warning:
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....

Why does PHP calculate -2.27373675443E-13 for (89.99*12) - 1079.88? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
php calculate float
The accuracy of PHP float calculate
Why does PHP calculate -2.27373675443E-13 for this...
echo (89.99*12) - 1079.88;
shouldn't it return 0?
floating point calculations are complicated and potentially inaccurate. this problem appears in every programming-language because decimal numbers can't be stored perfectly in binary representation.
to quote PHPs documentation about this:
Warning
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.

why 0.1+0.2-0.3= 5.5511151231258E-17 in php [duplicate]

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
The accuracy of PHP float calculate
when i executed the code below in eclipse , the result was not 0 but 5.5511151231258E-17
$a = 0.1+0.2-0.3;
echo $a;
could someone tell me why?
This is because floating point numbers have limited precision.
You can find more information about this trait on this page in the PHP manual.
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 progragation 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 never
compare floating point numbers for equality. If higher precision is
necessary, the arbitrary precision math functions and gmp functions
are available.
Please note that this is not a trait specific to PHP; it is just the way floating point numbers work.
You're running into PHP's floating point precision issues. All languages have them, you've just found PHP's.
This is not PHP specific, as others have mentioned. However, you can avoid limited floating point precision by using round():
<?php
$a = 0.1+0.3-0.2;
echo round($a, 2);
?>
Of course you will need to know the number of digits beforehand.
It's because computers can't accurately represent floating point numbers. This isn't specific to PHP.
See here for details.

0.699 x 100 = 69.89999999999999? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Why does 99.99 / 100 = 0.9998999999999999
Dealing with accuracy problems in floating-point numbers
I've seen this issue in php and javascript. I have this number: float 0.699
if I do this:
0.699 x 100 = 69.89999999999999
why?
edit
round(0.699 x 10, 2): float 69.90000000000001
Floating point arithmetic is not exact.
See Floating point on Wikipedia for a deeper discussion of the problem.
This is what has helped me in the past. It has a lot to do with how things are represented in binary. Basically long story short in binary there isn't an exact number for all real numbers of large numbers.
The link below will describe that in more detail for you.
What Every Computer Scientist Should Know About Floating-Point Arithmetic
This will happen in any language. Floats, like everything else on a computer, are stored as binary. The number 0.699, while representable exactly in decimal, is probably a repeating decimal in binary, so it can't be stored to exact precision.
Check out the wikipedia entry for how floats are stored, and why this happens.
Javascript numbers are floating point.
Take a look at The complete javascript number reference. Excerpt:
All numbers in Javascript are 64bit (8
bytes) floating point numbers which
yields an effective range of 5e-324
(negative) to 1.7976931348623157e+308
(positive) at the time this article
was written (this may eventually
change to 128 bits in the future as 64
bit processors become commonplace and
the ECMA standards evolve).
Integers are considered reliable
(numbers without a period or exponent
notation) to 15 digits (9e15) 1.
Floating point numbers are considered
only as reliable as possible and no
more! This is an especially important
concept to understand for currency
manipulation as 0.06 + 0.01 resolves
to 0.06999999999999999 instead of
0.07.
Take a look at Floating Point, specifically the section on IEEE 754 and representable numbers.
This behavior can be reproduced in many programming languages, including C++ and Assembly. The reason is floating point format using by FPU. You can read details here:
http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_14/CH14-1.html#HEADING1-19
General rule: never expect exact result of floating-point operations. Never compare two floating point numbers, use interval, for example: instead of testing f1 == f2, use f1 > (f2 -e) and f1 < ( f2 + e ), e is some small value.

Categories