I am entering '35444650.00' as a float into my MySQL and it keeps reformatting to 35444648.00, any help welcome...
Floats only have a certain level of precision, you may be going beyond how precise a float data type can be. Try using a DOUBLE instead.
A float has 6 digits of precision. Use a double to get 15 or switch to a numeric(x,y). If you're interested, check out the storage requirements for MySQL for the different data types.
The MySQL manual claims that FLOAT, REAL, and DOUBLE PRECISION fields stores values as approximate and INTEGER, SMALLINT, DECIMAL, and NUMERIC fields stores values as exact.
I think best bet to overcome this precision issue is to use decimal.
Reference: http://dev.mysql.com/doc/refman/5.1/en/numeric-types.html
A higher precision alternative to float is DOUBLE. But looking at the example, I think the DECIMAL datatype might come in handy if the number of digits required after zero is small (around 2-4) and the number of digits before decimal is also small (around 10-12).
You are going past the level of precision possible. You need to define the float with more precision, i.e. "FLOAT(10,5)" would mean a float that can have 10 digits total with up to five after the decimal point.
Related
Here is my table:
Let us suppose I want my account balance to be:
0.4729472846758294728572
So I tried to set it to it but it keeps cutting it off and rounding up.
How can I stop this behavior?
FLOAT values are approximate:
The FLOAT and DOUBLE types represent approximate numeric data values.
If you need arbitrary precision you can use a DECIMAL column instead, e.g. DECIMAL(25, 20). In this case you'll get 5 digits before the decimal and 20 after.
MySQL permits a nonstandard syntax: FLOAT(M,D) or REAL(M,D) or DOUBLE PRECISION(M,D). Here, (M,D) means than values can be stored with up to M digits in total, of which D digits may be after the decimal point. For example, a column defined as FLOAT(7,4) will look like -999.9999 when displayed. MySQL performs rounding when storing values, so if you insert 999.00009 into a FLOAT(7,4) column, the approximate result is 999.0001.
see here:https://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html,
http://code.rohitink.com/2013/06/12/mysql-integer-float-decimal-data-types-differences/
I have been working on a project with a lot of numbers inserted in a database table. Now that I finished the code, I was checking the values for errors and I noticed my value 3075277 would transform in 3075280 when inserted in the db and 3075255 would be 3075260.
The colummn type is Float. What should I change to disable the rounding? This one doesn't even have decimals numbers, why would it round like that? I use the default options, only changed collation to utf8_general_ci and change the type to varchar and lenght in some and float in others.
This issue is with MySQL, not Phpmyadmin.
FLOAT has 6-7 significant digits of precision, as you are seeing with the mangled values. By "significant digits", I mean starting anywhere:
1234567xxxx.
12345.67xxx
1.234567xxx
0.0000001234567xxx
That is the xxx is likely to be zeros or some kind of 'noise', not the original value you put into the column.
DOUBLE gives you about 16 significant digits.
DECIMAL(9,0) gives you 9 digits to the left of the decimal point, none afterwards. Sort of like INT.
DECIMAL(9,4) gives you 5 (9-4) digits to the left of the point; 4 afterwards.
What kinds of numbers are you storing? Money? Scientific measurements? Astronomical distances? DT's wealth?
Now you are using FLOAT type but getting error because you are saving big decimal number in the database. You should go for DOUBLE.
Although FLOAT and DOUBLE are similar because they store the value in approximate value, but that DOUBLE is 8-bytes, and FLOAT is 4-bytes.
A FLOAT is for single-precision, while a DOUBLE is for double-precision numbers.
MySQL uses four bytes for single-precision values and eight bytes for double-precision values.
There is a big difference from floating point numbers and decimal (numeric) numbers, which you can use with the DECIMAL data type. This is used to store exact numeric data values, unlike floating point numbers, where it is important to preserve exact precision, for example with monetary data.
So as in your case, for larger numbers you would want DOUBLE instead of FLOAT.
I am working with dollar amounts. In MySQL database the following fields fee and rate(percentage) are DECIMAL type with 2 decimal precision.
SELECT ROUND(fee * (1- rate/100))),2 ) as profit
from products
Since query is just returning the values instead of saving them in variables, does the precision problem* still exist (that comes with PHP or JS)? If so is it best to round the floating point number in PHP or JS?
*Yes I mean precision issue that occurs when saving double, e.g., 1.5 may be saved as 1.49999999
Others may have alluded to this, but I wanted to let you know my system for handling money calculations in PHP.
I use integers. The thing is that I have each increment represent the highest precision I need. For most of my applications, this is hundredths of a dollar, or one cent. However, you can have it be millionths or whatever you need.
So in practice, with the precision being in hundredths, $.01 is represented as 1, $.10 is represented as 10, $1.00 is represented as 100, and so forth. This really gets rid of the rounding issue as you are going to be manipulating integers only, since the decimal part of any computation will be truncated. This is OK, though, since the integer represents the finest precision you need.
Admittedly, this takes a bit more developing to handle, but rounding should not be one of the issues that crop up.
I have an customer invoice table in my MySQL database with a DECIMAL(10,2) field called price.
When fetching these values in php and calculating a sum amount,
ex: in the script
$totalAmount = 0; // initialised them to
while(records){
$amount = $inv_amount - ($pay_amount + $onamount); //float i guess. 2.22, 14.22
$totalAmount = $totalAmount + $amount; //float i guess. 2.22, 14.22 ..etc
}
when echo $totalAmount; it has a slight error in the final amount 0.01 however when dealing which large datasets around 20,000 this error becomes very considerable such as 200+
what is the safest way to do this when dealing with prices and such with these numbers in PHP? Or will I end up with potential rounding errors and things like that which are common when working with floating point data types?
is using
round
number_format
is the most suitable solution for this type of a financial application ?
Indeed, floating point numbers are not precise.
Either calculate in cent (multiply by 100 and calculate in integers), or calculate in strings using BC Math.
Try this:
$totalAmount = number_format($totalAmount, 2, '.', '');
If you need accuracy of 2 decimal points:
multiply value by 100
do your operations
divide by 100 and use number_format where appropriate
have you tried to
round(totalAmount, 2, PHP_ROUND_HALF_ODD);
it should see last decimal number - if it's odd - rounds down, if even - up
Well, to begin with, why sum in a php loop when you can do that in mysql? Moreover, just use integer multiplied by 100 and then divide by 100 once you need the final result.
You could use number_format
Ex:(for two decimal points)
$number = 12345.5667;
echo $result = number_format($number, 2);
Or you could use round function in MySql:
ROUND(number,2)
I recommend doing calculations on SQL Level with queries or views.
Firstly, using 64 bit integers on PHP is risky because; on overflow, it switches to float and you lose precision. When it's money, the problem is more serious. You should acually calculate a column with sql and just get the value from there. Money is a long type and it will often convert to float on php and your people will lose or win some cents depending on the mood of php engine. You can't work with decimal type on php, even if you multiply by 100 and keep it as an integer, long numbers with overflow will be converted to float automatically. Calculate your values on MYSQL if you want to use decimal numbers or convert your field into int.
If your server has an 32 bit cpu, the WORD length is 32 bit so integers in php engine are 32 bit integers. This makes the likelihood of overflow higher. On an 64 bit system, you can work more comfortably.
Using a round function on a money value is ridiculous and unprofessional in this case. Don't do it.
Reading this document will help you a lot.
php documentation of integers says
Integer overflow
If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.
Calculation on SQL level will ensure precision for money type. Getting the money type to php will result in a float value, and you can multiply it by 100 and divide by 100 later BUT it increases the rish of overflow again because php will use an 32 bit float number for storage. If you are using 32 bit float why is the data field decimal? So it's inconsistent if you do that. an 32 bit number i already not so big, and an 32 bit float loses some of its capacity on floating point, so it's more likely to reach over capacity when you multiply by 100.
USE SQL
24151.40 - 31891.10 = -7739.699999999997
I grab these two numbers from a MySQL table with the type as decimal(14,2)
24151.40
31891.10
It is saved exactly as stated above and it echos exactly like that in PHP. But the minute I subtract the second value from the first value, I get a number -7739.699999999997 instead of -7,739.7. Why the extra precision? And where is it coming from?
From an article I wrote for Authorize.Net:
One plus one equals two, right? How about .2 plus 1.4 times 10? That equals 16, right? Not if you're doing the math with PHP (or most other programming languages):
echo floor((0.2 + 1.4) * 10); // Should be 16. But it's 15!
This is due to how floating point numbers are handled internally. They are represented with a fixed number of decimal places and can result in numbers that do not add up quite like you expect. Internally our .2 plus 1.4 times 10 example computes to roughly 15.9999999998 or so. This kind of math is fine when working with numbers that do not have to be precise like percentages. But when working with money precision matters as a penny or a dollar missing here or there adds up quickly and no one likes being on the short end of any missing money.
The BC Math Solution
Fortunately PHP offers the BC Math extension which is "for arbitrary precision mathematics PHP offers the Binary Calculator which supports numbers of any size and precision, represented as strings." In other words, you can do precise math with monetary values using this extension. The BC Math extension contains functions that allow you to perform the most common operations with precision including addition, subtraction, multiplication, and division.
A Better Example
Here's the same example as above but using the bcadd() function to do the math for us. It takes three parameters. The first two are the values we wish to add and the third is the number of decimal places we wish to be precise to. Since we're working with money we'll set the precision to be two decimal palces.
echo floor(bcadd('0.2', '1.4', 2) * 10); // It's 16 like we would expect it to be.
PHP doesn't have a decimal type like MySQL does, it uses floats; and floats are notorious for being inaccurate.
To cure this, look into number_format, e.g.:
echo number_format(24151.40 - 31891.10, 2, '.', '');
For more accurate number manipulation, you could also look at the math extensions of PHP:
http://www.php.net/manual/en/refs.math.php
This has to do with general float / double precision rates, which scientifically relates to 1.FRACTAL * 2^exponential power. Being that there's a prefix of 1, there's technically no such thing as zero, and the closest value you can obtain to 0 is 1.0 * 2 ^ -127 which is .000000[127 0s]00001
By rounding off your answer to a certain precision, the round factor will give you a more precise answer
http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_round