This question already has an answer here:
Convert exponential to a whole number in PHP [duplicate]
(1 answer)
Closed 7 years ago.
I have data from csv, the contents of the column id look like this 6.61884E+17 6.61881E+17 6.61878E+17
This code not work, the results of this code remains the same :(
$a = '6.61884E+17';
$b = (string) floatval($a);
How to convert 6.61884E+17 to string ?
Update :
I try number_format(6.61884E+17,0,'','') and get 661884000000000000 as result. . my expected result is 661883847445868544
You want the number 661883847445868544 to be extracted from 6.61884E+17.
This isn't possible for you because of "integer overflow".
PHP handles this for you by converting it into a float (it's stupid because you can't perform basic arithmetic on them).
Now, if you run echo strval(661883847445868544); and get the same value back, you are running PHP 64 bit, and can handle that number. However, what is clear is that the program that created the CSV is 32 bit, and the largest integer values are:
2,147,483,647 signed
4,294,967,295 unsigned
After the value 6.61884E+17 is dumped, precision after the 6th digit is lost, and there is nothing you can do to bring it back. Sorry.
Related
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
On My PHP server Float values changes when i print on website in json format.
but working ok on localhost.
Code:
$float = 1.440030394;
$value = round($float,5); // 1.44003
$response = array();
$response['status'] = true;
$response['message'] = "success";
$response['values'] = $value;
echo json_encode($response);
// test if value is really true?
echo "<br>test<br>";
echo $value."-abc"; // Work ok if float convert to string
Localhost Response is ok, but on Live server response is
{
"status": true,
"message": "success",
"values": 1.44035442150000012452200154
}
Test
1.44003-abc
Any solutions? i try functions : round, number_format but not working.
Float uses mantissa and exponent representation to hold a number. That means that not all bits of the value are saved separately, and this results in an impossibility to represent all numbers.
You can see this for more details: How are floating point numbers stored in memory?.
Basically your number cannot be stored in a float, so any operations you do on it will result in a slight error.
You have 2 options here.
First one is that if the error is not too big for you and you can ignore it, you just need to truncate the number on output result.
Second one is to treat the number like a string or save each individual digit inside an array. This is actually what happens when you converted your number to string on your last edit. Your number is not a number any more, but a string and each of its digits are saved individually.
Almost all languages are based on float for numbers with decimals because of their versatility, but floats should not be used for data where each bit is important (like for money). You can open your console in browser (f12 by default and type 0.8 - 0.7) the output will be 0.100000000009 or something like that, because 0.1 doesn't have an exact representation, but the error is small enough to be ignored usually.
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
Am having an issue where PHP expands the float value e.g. 241.09 becomes 241.0899999999. The issue is, the expanded value is included in a signature, thus the expansion is causing my signature to have a mismatch when matching with the actual data which has the original unexpanded form. How do I prevent the rounding off? My code section is as below:
round(floatval($resultParams["AvailableFunds"]), 2)
Somehow, even after applying the round function, the expansion still occurs. How do I prevent that??
It's caused by the PHP Floating point precision:
Floating point numbers have limited precision.
A solution may be to use only integer, e.g. save the float 123.45 as 12345 and when you need to use display it divide it by 100 and pass it to the number_format function:
$myNumView = number_format($myNum/100, 2, '.', '')+0;
By doing this, number_format returns a string formatted as 1234567.89, then by doing +0 PHP converts it to float (due to the PHP Type Juggling) and removes the rightmost 0 in the decimal part of the number:
$a = '35';
$b = '-34.99';
echo $myNum = ($a + $b);
echo '<br>';
echo $myNumView = number_format($myNum, 4, '.', '')+0;
returns:
0.009999999999998
0.01
And also, why does you get AvailableFunds from a string with floatval? It seems that AvailableFunds is a string containing the amount of fund and other text. I think this is a bad implementation on how saving the fund amount. It's better to save the value as is in a dedicated field as float.
This question already has answers here:
How to mathematically evaluate a string like "2-1" to produce "1"?
(9 answers)
Closed 3 years ago.
I am dealing with exif data acquired via php , and I see that the DPI of a scanned image can return 300/1 or 600/1 for example
I am not sure if this is normal but google tells me it is common. I do not know if this means I may see 300/2 (150DPI)
When I get this variable from exif, I want to treat it as a math problem that needs simplifying or in math terms 300 / 1 =300 therefore 300. As it is a string I have no idea how to tell php to simplify the math in the string.
Any ideas?
Assuming the string contains something like 300 It sounds like you're looking to cast your string to an integer with something like (int)$exif_string. If it contains something like 300/1, you can use substr($exif_string, 0, 3) to grab only the first three characters.
Once you have an integer variable, you can make your calculations on it:
$dpi = (int)substr($exif_string, 0, 3);
$dpi_value = $dpi / 300;
eval() would be a possible alternative, though I would recommend against this, due to the fact that it can allow arbitrary execution of code.
I've read all over about arithmetic regarding floating point numbers, but I'm just trying to accurately store the darn things.
I have a mysql field with the type of DECIMAL (40,20).
I am saving a value in php of 46457.67469999996. After updating the record with this value, the end result is 46457.67470000000000000000. Not sure why it's being rounded at all just being saved to the database.
The value is not being converted to a string or anything beforehand. The field value that is passed into PDO is the value I expected to be saved and it is returned as a float... Perhaps it's because I'm saving a PHP float to a mysql decimal type where the rounding is occurring?
What am I missing here?
EDIT: Added example code that has the issue
// Query placeholder variables. Hard-coded for the example test
$query_vars = array(
":vendor_id" => 33154,
":year" => 2018,
":coop_committed_dollar" => 46457.67469999996,
":coop_committed_dollar_update" => 46457.67469999996
);
$statement = " INSERT INTO vendor_data_yearly
(vendor_id, year, coop_committed_dollar) VALUES
(:vendor_id, :year, :coop_committed_dollar)
ON DUPLICATE KEY UPDATE
coop_committed_dollar = :coop_committed_dollar_update;";
$query = $connection->conn->prepare($statement);
$query->execute($query_vars);
When I run this, the resulting value of coop_committed_dollar is 46457.67470000000000000000. This code is legit all I am doing.
Possible solution
// Note that I am casting the string using the BC Math library.
// I dunno how to just initialize the number (lame documentation), so I'm adding 0 to it.
$number = "46457.674699999967";
$number = bcadd("46457.674699999967", 0, 20);
$query_vars = array(
":vendor_id" => 33154,
":year" => 2018,
":coop_committed_dollar" => $number,
":coop_committed_dollar_update" => $number
);
$statement = " INSERT INTO vendor_data_yearly
(vendor_id, year, coop_committed_dollar) VALUES
(:vendor_id, :year, :coop_committed_dollar)
ON DUPLICATE KEY UPDATE
coop_committed_dollar = :coop_committed_dollar_update;";
$query = $conn->prepare($statement);
$query->execute($query_vars);
This results in the number as expected in the DB.
ONLY SOLUTION I FOUND TO WORK CORRECTLY
The data I am working with is passed in via ajax. I had to take a few steps to get this to work correctly.
Use ini_set('precision', 20);
Manually set the data in question to be a string BEFORE sending it via ajax so PHP would not round it, extended with extra floating point madness, padd it, etc.
I found that PHP would just not let me reliably work with large numbers coming from a variable set outside the script's scope (ajax). Once PHP got it's hands on the number, it would do what it had to do in order to make it make sense as a float.
If anyone has a better solution for this particular scenario I'm all ears and eyes :)
The problem is that PHP's precision is not allowing you to store the exact number you think you are storing.
When you set ":coop_committed_dollar" => 46457.67469999996
PHP is actually storing it as a different value, depending on the precision.
The solution is to store the value in PHP as a string instead of a float.
Since your question is: "what am I missing", I will try to provide an answer.
Basically it comes down to storing floats internally using binary representation. Since 46457.67469999996 cannot be exactly in binary (it ends up with an infinite number, similar to 33% (.3333...) in base-10), the closest rounding is used based on PHP's precision (set in php ini).
I was given a great explanation in this question that I asked a while back.
In your particular case, it also seems that the value that you are sending via AJAX is being stored as a float when parsed by PHP on the server-side. You want it to be stored as a string instead. If you're using json_decode, add this option: JSON_BIGINT_AS_STRING.
This question already has answers here:
Print numeric values to two decimal places
(6 answers)
Closed 11 months ago.
I'm saving numbers in MySQL using double(10,2).
The numbers are getting saved like:
456.2
232.20
764
On output, I want to force 2 decimals and add the necessary trailing zeros (currency).
Here is the function I'm using and it isn't working.
function format_currency_form($get_money) {
$money_output = abs(number_format($get_money, 2, '.', ''));
return $money_output;
}
(I'm using ABS because I want the value to display as a positive number regardless of its true value in the db)
Here is the code block used to output the data:
<?php echo format_currency_form($row_rs_data['trans_amount']); ?>
No errors getting thrown and no trailing zeros...
Any ideas?
Thanks
Brett
If you are dealing with currency try to use moneyformat
http://php.net/manual/en/function.money-format.php
money_format('%.2n', $number)
In your case the abs should be done in this way:
$number=-11.44;
$money_output = money_format('%.2n', abs($number));
echo $money_output;
If you are dealing with currencies (I think so) money_format gives you a lot of options.
Use sprintf to output formatted strings.
echo sprintf("%.2f", format_currency_form($blah_blah));