How do I store decimals with USER-specified precision in MySQL? - mysql

I have an application in which users are typing measured amounts. I would like to respect the precision they are entering when storing the values in MySQL, i.e. if they type 0.050 I don't want that to become 0.05 since that is loosing information on how exact the measurement was done. Is there a way other than storing the value as a string?

0.050 is equal to 0.05 . If you want 3 digits after comma, you have to implement this feature in application.

As per my knowledge for handling precision point we are using FLOAT, DOUBLE or DECIMAL data types. In your case if you are not using any function like SUM(),AVG(),etc then you can use VARCHAR.

Add always a "control" digit, lets say "1", save to database, then get data from database and always trim ONE time the "control" digit "1" from what you've got.
example:
user inputs 0,000050
save as 0,0000501
get the 0,0000501
trim the last "1" (only the last one be carefull)
k.i.s.s. people :D
edit: proper solution of course, add a column to store precision and right-pad zeroes if needed

Related

Data type for price with positive number max. 4 digits before and after the comma [duplicate]

I setup a database/website recently where the members have points scored against them.
There are 3 points fields (corresponding to different activities). And the Sum of those 3 fields = their total points.
Initially, I understood they'd always be whole numbers not totally more than 30. So I set the point fields to INT
Now they need to be able to have quarter (.25) and half points (.5) assigned.
Am I best to change these points fields to FLOAT(2,2)?
I would use a DECIMAL(4,2). 4 is the precision (the total number of digits); 2 is the scale (the number of digits to the right of the decimal point).
From the MySQL Reference:
Fixed-Point (Exact-Value) Types
The DECIMAL and NUMERIC types store exact numeric data values. These types are used when it is important to preserve exact precision, for example with monetary data. In MySQL, NUMERIC is implemented as DECIMAL, so the following remarks about DECIMAL apply equally to NUMERIC.
Alternately, you could just store an int that represents 4 times the "actual" score.
Example: 4.25 would be represented in the database as 17.
depending on what you are doing it may be easier to store the points as .25->1, .5->2, 1->4 (as in number of quaters) that way you can use an int still and just format the output when it is displayed.
Short answer: Yes.
Yes if you want to have decimal points you can either yes FLOAT(M,D) , REAL(M,D) or DOUBLE PRECISION(M,D) however there is some know issues involved with MySQL Float which is more or less depending on the Platform.
There is automated rounding with FLOAT field which could be a bad or good thing depending on what you want for example if you insert 999.00009 into a FLOAT(7,4) column, the approximate result is 999.0001.
you can use DECIMAL(M,D)(fixed point representation) for accuracy otherwise Float is also a good choice.

Storing statistical data, do I need DECIMAL, FLOAT or DOUBLE?

I am creating for fun, but I still want to approach it seriously, a site which hosts various tests. With these tests I hope to collect statistical data.
Some of the data will include the percentage of the completeness of the tests as they are timed. I can easily compute the percentage of the tests but I would like true data to be returned as I store the various different values concerning the tests on completion.
Most of the values are, in PHP floats, so my question is, if I want true statistical data should I store them in MYSQL as FLOAT, DOUBLE or DECIMAL.
I would like to utilize MYSQL'S functions such as AVG() and LOG10() as well as TRUNCATE(). For MYSQL to return true data based off of my values that I insert, what should I use as the database column choice.
I ask because some numbers may or may not be floats such as, 10, 10.89, 99.09, or simply 0.
But I would like true and valid statistical data to be returned.
Can I rely on floating point math for this?
EDIT
I know this is a generic question, and I apologise extensively, but for non mathematicians like myself, also I am not a MYSQL expert, I would like an opinion of an expert in this field.
I have done my research but I still feel I have a clouded judgement on the matter. Again I apologise if my question is off topic or not suitable for this site.
This link does a good job of explaining what you are looking for. Here is what is says:
All these three Types, can be specified by the following Parameters (size, d). Where size is the total size of the String, and d represents precision. E.g To store a Number like 1234.567, you will set the Datatype to DOUBLE(7, 3) where 7 is the total number of digits and 3 is the number of digits to follow the decimal point.
FLOAT and DOUBLE, both represent floating point numbers. A FLOAT is for single-precision, while a DOUBLE is for double-precision numbers. A precision from 0 to 23 results in a 4-byte single-precision FLOAT column. A precision from 24 to 53 results in an 8-byte double-precision DOUBLE column. FLOAT is accurate to approximately 7 decimal places, and DOUBLE upto 14.
Decimal’s declaration and functioning is similar to Double. But there is one big difference between floating point values and decimal (numeric) values. We use DECIMAL data type to store exact numeric values, where we do not want precision but exact and accurate values. A Decimal type can store a Maximum of 65 Digits, with 30 digits after decimal point.
So, for the most accurate and precise value, Decimal would be the best option.
Unless you are storing decimal data (i.e. currency), you should use a standard floating point type (FLOAT or DOUBLE). DECIMAL is a fixed point type, so can overflow when computing things like SUM, and will be ridiculously inaccurate for LOG10.
There is nothing "less precise" about binary floating point types, in fact, they will be much more accurate (and faster) for your needs. Go with DOUBLE.
Decimal : Fixed-Point Types (Exact Value). Use it when you care about exact precision like money.
Example: salary DECIMAL(8,2), 8 is the total number of digits, 2 is the number of decimal places. salary will be in the range of -999999.99 to 999999.99
Float, Double : Floating-Point Types (Approximate Value). Float uses 4 bytes to represent value, Double uses 8 bytes to represent value.
Example: percentage FLOAT(5,2), same as the type decimal, 5 is total digits and 2 is the decimal places. percentage will store values between -999.99 to 999.99.
Note that they are approximate value, in this case:
Value like 1 / 3.0 = 0.3333333... will be stored as 0.33 (2 decimal place)
Value like 33.009 will be stored as 33.01 (rounding to 2 decimal place)
Put it simply, Float and double are not as precise as decimal. decimal is recommended for money related number input.(currency and salary).
Another point need to point out is: Do NOT compare float number using "=","<>", because float numbers are not precise.
Linger: The website you mention and quote has IMO some imprecise info that made me confused. In the docs I read that when you declare a float or a double, the decimal point is in fact NOT included in the number. So it is not the number of chars in a string but all digits used.
Compare the docs:
"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"
http://dev.mysql.com/doc/refman/5.1/en/floating-point-types.html
Also the nomenclature in misleading - acc to docs: M is 'precision' and D is 'scale', whereas the website takes 'scale' for 'precision'.
Thought it would be useful in case sb like me was trying to get a picture.
Correct me if I'm wrong, hope I haven't read some outdated docs:)
Float and Double are Floating point data types, which means that the numbers they store can be precise up to a certain number of digits only.
For example for a table with a column of float type if you store 7.6543219 it will be stored as 7.65432.
Similarly the Double data type approximates values but it has more precision than Float.
When creating a table with a column of Decimal data type, you specify the total number of digits and number of digits after decimal to store, and if the number you store is within the range you specified it will be stored exactly.
When you want to store exact values, Decimal is the way to go, it is what is known as a fixed data type.
Simply use FLOAT. And do not tack on '(m,n)'. Do display numbers to a suitable precision with formatting options. Do not expect to get correct answers with "="; for example, float_col = 0.12 will always return FALSE.
For display purposes, use formatting to round the results as needed.
Percentages, averages, etc are all rounded (at least in some cases). That any choice you make will sometimes have issues.
Use DECIMAL(m,n) for currency; use ...INT for whole numbers; use DOUBLE for scientific stuff that needs more than 7 digits of precision; use FLOAT` for everything else.
Transcendentals (such as the LOG10 that you mentioned) will do their work in DOUBLE; they will essentially never be exact. It is OK to feed it a FLOAT arg and store the result in FLOAT.
This Answer applies not just to MySQL, but to essentially any database or programming language. (The details may vary.)
PS: (m,n) has been removed from FLOAT and DOUBLE. It only added extra rounding and other things that were essentially no benefit.

Mysql - which datatype is best for values from 0 to 30.25 with no more than 2 decimal places of precision?

I setup a database/website recently where the members have points scored against them.
There are 3 points fields (corresponding to different activities). And the Sum of those 3 fields = their total points.
Initially, I understood they'd always be whole numbers not totally more than 30. So I set the point fields to INT
Now they need to be able to have quarter (.25) and half points (.5) assigned.
Am I best to change these points fields to FLOAT(2,2)?
I would use a DECIMAL(4,2). 4 is the precision (the total number of digits); 2 is the scale (the number of digits to the right of the decimal point).
From the MySQL Reference:
Fixed-Point (Exact-Value) Types
The DECIMAL and NUMERIC types store exact numeric data values. These types are used when it is important to preserve exact precision, for example with monetary data. In MySQL, NUMERIC is implemented as DECIMAL, so the following remarks about DECIMAL apply equally to NUMERIC.
Alternately, you could just store an int that represents 4 times the "actual" score.
Example: 4.25 would be represented in the database as 17.
depending on what you are doing it may be easier to store the points as .25->1, .5->2, 1->4 (as in number of quaters) that way you can use an int still and just format the output when it is displayed.
Short answer: Yes.
Yes if you want to have decimal points you can either yes FLOAT(M,D) , REAL(M,D) or DOUBLE PRECISION(M,D) however there is some know issues involved with MySQL Float which is more or less depending on the Platform.
There is automated rounding with FLOAT field which could be a bad or good thing depending on what you want for example if you insert 999.00009 into a FLOAT(7,4) column, the approximate result is 999.0001.
you can use DECIMAL(M,D)(fixed point representation) for accuracy otherwise Float is also a good choice.

Allow number to start with ZERO when stored in mysql integer field

I need to store phone numbers starting with 0 but whenever i try to store this in MySql table the starting ZERO is removed because no number start with Zero actually.
How to solve this issue? Do I need to change the field type from Integer to another type?
change data type to unsigned-zerofill whatever you are using, float, int, decimal(6,2)... only edit the field to unsigned-zerofill
Phone numbers are not really numbers in the sense that they aren't ordinal. They're just characters - they fact that they are numbers is incidental.
Store them in a varchar and move on :D
Phone numbers can contain other symbols for readability too... a regexp for a phone number looks something like [0-9+-()*#]+. So you need to use a text field for phone numbers, plus some validation.
You can use data type as varchar to solve this.
Phone numbers aren't integers and you will only end up with problems trying to store them as integers, store them as strings instead.
Yes - numeric fields only store the numeric values, not the formatting of those (which paddin with leading zeroes is). You should either
change the field type from integer to varchar or char (if # of digits is ALWAYS the same).
Store the number as integer BUT prepend 0 in your presentation layer as needed.
You can also wrap the number you want with a lead zero with a function. I made this function to add lead zero if the "string" is smaller than 2 digits (it was used to add lead zeroes to hours and minutes)
function leadZero($num) {
if (strlen($num) < 2) {
return "0" . $num;
} else {
return $num;
}
}
If you have say, a number 2 that you want to output as 02, you'd do leadZero(2);
This will only add a zero IF the number is less than 2 digits long ! For instance leadZero(14); will return 14

MySQL FLOAT & decimals

Datatype of field in the DB is FLOAT and the value is 18.7. I'd like to store and display this on page as 18.70. Whenever I enter the extra 0 it still only stores it as 18.7
How can I store the extra 0 ? I can change the data type of the field.
In a FLOAT column, what MySQL stores for 18.7, is actually:
01000001 10010101 10011001 10011010
which, being retrieved from the DB and converted back into your display format, is 18.7.
In reality, the stored value is a binary fraction represented by the decimal number 18.70000076293945 which you can see by issuing this query:
CREATE TABLE t_f (value FLOAT);
INSERT
INTO t_f
VALUES (18.7);
SELECT CAST(value AS DECIMAL(30, 16))
FROM t_f;
IEEE-754 representation of number stores them as binary fractions, so a value like 0.1 can only be represented with continued fraction and hence be not exact.
DECIMAL, on the other hand, stores decimal digits, packing 9 digits into 4 bytes.
Floating point types do not store the number of insignificant zeros on the left side of a number before decimal digit or on the right side of the number after the decimal digit. You'll need to use a string-based type (or store the precision in a separate field) if you want to store the exact numeric string entered by the user and be able to distinguish 12.7 from 12.70. You can, however, round things that you display by two digits in your application.
if two decimal points needed use:
decimal(n,2); where n>=2
the decimal data type will persist the decimal points formatting and gives more accurate results than float and double data types.
Are you attempting to store a currency as a float? If so, please use a decimal with more decimal digits than 2.
You really want fixed-point arithmetic on currencies.
This is just very broad rule of thumb and my own observation, but in regular business logic as serialized in a database, you almost never want floating point. I know there are lots of exceptions, but I'm suspicious whenever I see a float typed column in a table because of this. I'd be interested in what others have found.