Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exact decimal division in MySQL

How to properly divide two DECIMAL values in MySQL and get a result accurate to the number of digits defined in the column type?

Example:

select cast(1/2 as decimal(4,4)),
cast(1 as decimal(4,4))/2,
cast(1 as decimal(4,4))/cast(2 as decimal(4,4));

Results:

'0.5000', '0.49995000', '1.00000000'

Why is the second result innacurate? Why is the third result not '0.5000'?

Note: I can't just use the first form, I need to perform calculations with columns stored as decimals.

like image 926
Ferdinand.kraft Avatar asked Apr 02 '15 20:04

Ferdinand.kraft


People also ask

Can you do division in MySQL?

MySQL allows you to divide integer or floating point numbers by using the division operator ( / ) or the integer division DIV operator. The division operator returns a floating number even when the division result is an integer.

How do you set DECIMAL precision in SQL?

To store numbers that have fixed precision and scale, you use the DECIMAL data type. In this syntax: p is the precision which is the maximum total number of decimal digits that will be stored, both to the left and to the right of the decimal point. The precision has a range from 1 to 38.

What is precision in MySQL?

For example: salary DECIMAL(5,2) In this example, 5 is the precision and 2 is the scale. The precision represents the number of significant digits that are stored for values, and the scale represents the number of digits that can be stored following the decimal point.


1 Answers

The problem is that DECIMAL data type declaration requires 2 arguments, the first one being the total number of digits, including the fractional part.

According to the docs (http://dev.mysql.com/doc/refman/5.7/en/precision-math-decimal-characteristics.html):

The declaration syntax for a DECIMAL column is DECIMAL(M,D). The ranges of values for the arguments in MySQL 5.1 are as follows:

M is the maximum number of digits (the precision). It has a range of 1 to 65. (Older versions of MySQL permitted a range of 1 to 254.)

D is the number of digits to the right of the decimal point (the scale). It has a range of 0 to 30 and must be no larger than M.

So if you use 5 total digits instead of 4, everything is ok:

select cast(1/2 as decimal(5,4)),
cast(1 as decimal(5,4))/2,
cast(1 as decimal(5,4))/cast(2 as decimal(5,4)),
cast(cast(1 as decimal(5,4))/cast(2 as decimal(5,4)) as decimal(5,4));

Results

0.5000, 0.50000000, 0.50000000, 0.5000
like image 80
Ferdinand.kraft Avatar answered Sep 21 '22 17:09

Ferdinand.kraft