Display float value w/o scientific notation - php

When i make the following multiplication in PHP:
$ret = 1.0 * 0.000000001;
i get the result: 1.0E-9
I want to convert this result into the normal decimal notation, how can i do this?
sprintf('%f',$ret) doesn't work, it returns 0.000000. Overflow?

sprintf('%f',$ret) doesn't work, it returns 0.000000. Overflow?
sprintf works, however you miss some point here.
0.000000 is not overflow. It's just that sprintf for the %f modifier uses 6 digits per default. Also please take care that %f is locale aware, %F is probably better suited.
You might want to use more digits, e.g. let's say 4 000 000 (four million):
$ php -r "printf('%.4000000F', 1*0.000000001);"
Notice: printf(): Requested precision of 4000000 digits was truncated to PHP maximum of 53 digits in Command line code on line 1
Call Stack:
0.0001 319080 1. {main}() Command line code:0
0.0001 319200 2. printf() Command line code:1
0.00000000100000000000000006228159145777985641889706869
As this example shows, there is not only a common value (6 digits) but also a maximum (probably depended on the computer system PHP executes on), here truncated to 53 digits in my case as the warning shows.
Because of your question I'd say you want to display:
0.000000001
Which are nine digits, so you need to write it that way:
sprintf('%.9F',$ret)
However, you might want to do this:
rtrim(sprintf('%.20F', $ret), '0');
which will remove zeroes from the right afterwards:
0.000000001
Hope this is helpful.

You need to add precision specifier (how many decimal digits should be displayed for floating-point numbers). Something like this:
echo sprintf('%.10f',$ret); // 0.0000000010
If you have no idea what number you should specify, just give it a big number and combine it with rtrim().
echo rtrim(sprintf('%.20f', $ret), '0'); // 0.000000001
The code above will strip any 0's from the end of the string.

I suggest the use BCMath for more accuracy when you are calculating with decimal numbers. That makes sure that you actually get the results you want.
To print what you want, you should specify the precision and use %.9f, since it defaults to displaying 6 decimal numbers. That makes it something like this (just like bsdnoobz already said):
sprintf('%.9f',$ret);

To align to your system's settings and limitations, you could use serialize_precision to get the most accurate result possible.
echo rtrim(sprintf('%.'.ini_get('serialize_precision').'f', $ret));
I do not recommend using the non-locale aware %F since your question only makes sense for display purposes. Respecting locale makes for a better UX.

Related

number management with 16 decimals

I need to use numbers with 16 decimal places in a project and do math operations with them, but I have problems with their handling.
Whatever it does in php, these are truncated if they are too long.
such as if:
$value = 123456789.1234567890;
Printing it with "echo" the result I have on the screen is this: 123456789.12346
Even if the number has few elements in the integer part, the decimal part is truncated
$value = 0.12345678901234567890;
In output I have:
0.12345678901235
What can I do to manage them easily?
Thanks for your help.
I tried using the instruction suggested by GuidoFaecke:
ini_set('precision', '16')
Or:
ini_set('precision', '-1');
But when I use -1 I don't see decimal number. Using 16 I don't see changing showing the number.

Why strlen doesn't work in a paticular digit

I made this function. It seemed it's working but when it comes to 20 digits number, the return value was 19. I'm wondering why this problem happen..
My function
function sumDigits($n) {
return strlen($n);
}
echo sumDigits(100); //3
echo sumDigits(1000); //4
echo sumDigits(12345); //5
echo sumDigits(1000000000); //10
echo sumDigits(145874589632); //12
echo sumDigits(0); //1
echo sumDigits(12345698745254856320); //19 <-- Why not 20?
Can you please somebody explain for me?
Thank you so much.
First, I would point out that the name of your function is misleading, as you are not really summing the values of the digits, but are counting the digits. So I would call your function countDigits instead of sumDigits.
The reason why it doesn't work for large numbers, is that the string representation will switch to scientific notation, so you're actually getting the length of "1.2345698745255E+19" not of "12345698745254856320"
If you are only interested in integers, you will get better results with the logarithm:
function countDigits($n) {
return ceil(log10($n));
}
For numbers that have decimals, there is no good solution, since the precision of 64-bit floating pointing point numbers is limited to about 16 significant digits, so even if you provide more digits, the trailing decimals will be dropped -- this has nothing to do with your function, but with the precision of the number itself. For instance, you'll find that these two literals are equal:
if (1.123456789123456789123456789 == 1.12345678912345678) echo "equal";
Because you function parameter is an integer, exceeding the limit.
If you dump it, it actually shows the following:
1.2345698745255E+19 - which is 19 letters.
If you would do the following, it will return 20 - mind the quotes, which declares the input as string.
echo sumDigits("12345698745254856320"); //19 <-- Why not 20? -> now will be 20
As per documentation, strlen() expects a string so a cast happens. With default settings you get 1.2345698745255E+19:
var_dump((string)12345698745254856320);
string(19) "1.2345698745255E+19"
The root issue is that PHP converts your integer literal to float because it exceeds PHP_INT_MAX so it cannot be represented as integer:
var_dump(12345698745254856320, PHP_INT_MAX);
In 64-bit PHP:
float(1.2345698745254857E+19)
int(9223372036854775807)
You could change display settings to avoid E notation but you've already lost precision at this point.
Computer languages that store integers as a fixed amount of bytes do not allow arbitrary precision. Your best chance is to switch to strings:
var_dump('12345698745254856320', strlen('12345698745254856320'));
string(20) "12345698745254856320"
int(20)
... and optionally use an arbitrary precision library such as BCMath or GMP if you need actual maths.
It's also important to consider that this kind of issues is sometimes a symptom that your input data is not really meant to be an integer but just a very long digit-only string.

PHP Long string. Output it all

So I got a really long string, made by a calculator.
$string='483451102828322427131269442894636268716773727170';
$result=(8902543901+$string)*($string/93.189)/($string)+55643907015.57895461;
echo $result;
This outputs 5.1878558931668E+45
So now my question is. How can I output the whole string, without that nasty E+45?
PHP on a 64 bit machine can only accurately calculate number up until 9223372036854775807. As soon as you calculate with numbers higher than that, php will switch to floats which may loose some of it's precision, especially when you use divisions.
There's an extension for php that will allow you to make calculations based on string, called BCMath.
Example:
$string = '483451102828322427131269442894636268716773727170';
$result = bcadd($string, 8902543901);
echo $result;
bcadd() is for additions, bcdiv() for divisions and bcmul() for multiplying.
You can't print exact value because you are using calculation, so this $string becomes a number (float in this case) and all numbers have limited precision.
If you want to do operations on big numbers you should use BCMath
However if you want to display it without scientific notation you can do it using:
echo sprintf("%f",$result);
or
echo sprintf("%.0f",$result);
if you want to omit decimal part

Round function php

Maybe the question is simple, but I can't find the answer.
What I need to do is to round number to 2 places after comma.
Im using this:
round(($data/$count*100), 2)
And when I get number like:
60.36036036036012 and : 37.83783783783808 is OK, because it's: 60.36 and 37.84
But why this:
1.8018018018018036
Is rounded to this:
1.8000000000000003
How to round always to 2 places, after comma?
You should get 1.8 unless you use something like old PHP version with some sort of related bugs. Still, if you want to see 1.80 you need to format output string, otherwise trailing zero will be stripped by default. The most flexible approach would be to use sprintf() formatting, like this:
$val = 1.8000000000000003;
printf("%.02f", round( $val, 2 ));
which would produce
1.80
The key is "%.02f" which means you want to format (f)loating point value, with two digits after dot, padded with 0 when needed (like this case).
See the sprintf() docs for more about available formatting possibilites.
Use PHP NumberFormatter class http://es.php.net/manual/es/class.numberformatter.php

Convert a big integer to a full string in PHP

I've been searching for a while now, but what I can find is not what I search for. I need to convert an integer value, that may be very huge, to a string. Sounds easy: "$var"? No, because this can lead to the E+ representation of the number.
<?php
$var = 10000000000000000000000000;
echo $var."\n";
echo "'$var'\n";
echo (string) $var."\n";
echo strval($var);
?>
1.0E+25
'1.0E+25'
1.0E+25
1.0E+25
How can I make the output be 10000000000000000000000000 instead?
This is not stored as an integer by PHP, but a float, this is why you end up with 1.0E+25 instead of 10000000000000000000000000.
It's sadly not possible to use that as an integer value in PHP, as PHP cannot save an integer of that size. If this comes from database then it will be a string and you can do with it whatever you want. If you store it elsewhere then store it as a string.
Your alternative is to store it as a float and take that into account at all times, though that requires additional conversions and handling in places.
It's also been suggested to use GNU Multiple Precision, but that's not enabled in PHP by default.
$int=gmp_init("10000000000000000000000000");
$string=gmp_strval($int);
echo $string;
UPDATE:
Found the next post:
// strval() will lose digits around pow(2,45);
echo pow(2,50); // 1.1258999068426E+015
echo (string)pow(2,50); // 1.1258999068426E+015
echo strval(pow(2,50)); // 1.1258999068426E+015
// full conversion
printf('%0.0f',pow(2,50)); // 112589906846624
echo sprintf('%0.0f',pow(2,50)); // 112589906846624
Use printf or sprintf.
I'm facing this problem when getting facebook id and find it in MySQL.
And after half hour, i found this work perfectly!
Insert this line to your php script:
ini_set('precision',30);
From: https://forums.phpfreaks.com/topic/125907-solved-convert-big-number-to-string/#entry651084
The integer number you like to express:
$var = 10000000000000000000000000;
is not available on your system. It's too large and therefore PHP converts it into a float which will change the number (32 bit system example):
10000000000000000905969664
Common limits are:
yours : 10 000 000 000 000 000 000 000 000
32 bit: 2 147 483 648
64 bit: 9 223 372 036 854 775 808
The change of the value is called floating point precision, the PHP manual about integers will tell you about the integer limit and the floats page about floating point precision (see the big red warning). Depending on which system you are, you can compile PHP with the ranges your application needs or you must use another datatype, for example with the gmp library which is able to pick strings as integer numbers and handle them.
The following example shows just output, but you can do multiplications etc.:
$r = gmp_init('10000000000000000000000000');
echo gmp_strval($r);
Hope this is helpful.

Categories