The round function sometime doesn't work very well. I have in my db a row like this:
field_1= 375
field_2= 0.65
field_3= 0.1
field_4= 11
So we know that: field_1*field_2*field_3*field_4 = 268.125 so if I round it to 2 decimals -> 268.13.
But in mysql I got 268.12 -> Select round(field_1*field_2*field_3*field_4) from my table -> 268.12
This situation just happens with these values, I tried with other numbers and no problem the round works.
Any workaround about it. I tried in mysql 4.1.22, and 5.1.44 and I get the same issue. I read in other forum http://bugs.mysql.com/bug.php?id=6251 that it is not a bug, they said that it depends on the C library implementation.
What data type are you using for those columns?
If you want exact precision then you should use NUMERIC or DECIMAL, not FLOAT, REAL, or DOUBLE.
From the manual:
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.
If applicable you can use FLOOR()
If not applicable you will be better off handling this on the application side. I.e. do the entire calculation application side and then round, or just round application side.
SELECT (field_1*field_2*field_3*field_4) AS myCalculation FROM my table
Related
I have two fields, both have the size set to double in the table properties. When I subtract one field from the other some of the results are displayed as scientific notation when I click in the cell and others just show regular standard format to decimal places.
The data in both fields was updated with Round([Field01],2) and Round([Filed2],2) so the numbers in the fields should not be any longer than 2 decimal places.
Here's an example:
Field1 = 7.01
Field2 = 7.00
But when I subtract Field1 from Field2 the access display shows 0.01 but when I click on the result it displays, -9.99999999999979E-03. So of course, when I try to filter on all results that have 0.01 the query comes back empty because it thinks the result is -9.99999999999979E-03.
Even stranger is if Field1 = 1.02 and Field2 = 1.00, the result is 0.02 and when I click on the result the display still shows 0.02 and I can filter on all results that equal 0.02.
Why would MS Access treat numbers in the same query differently? Why is it displaying in Scientific Notation and not filtering?
Thanks for any support.
Take this simple code in Access (or even Excel) and run it!
Public Sub TestAdd()
Dim MyNumber As Single
Dim I As Integer
For I = 1 To 10
MyNumber = MyNumber + 1.01
Debug.Print MyNumber
Next I
End Sub
Here is the output of the above:
1.01
2.02
3.03
4.04
5.05
6.06
7.070001
8.080001
9.090001
10.1
You can see that after just 7 additions rounding is occurring!
Note how after JUST 7 simple little additions Access is now spitting out wrong numbers and has rounding errors!
More amazing? The above code runs the SAME in Excel!
Ok, I am sure I have your attention now!
If I recall, the FIRST day and first class in computing science? Computers don't store exact numbers when using floating point numbers.
So, then how is it possible that the WHOLE business community using Excel, or Access, or in fact your desktop calculator not come crashing down?
You mean Access cannot add up 7 simple little numbers without having errors?
How can I even do payroll then?
The basic concept and ALL you need to know here is that computers store real (floating) numbers only as approximate.
And integer values are stored exact.
so, there are several approaches here, and in fact if you writing ANY business software that needs to work with money values? And not suffer rounding errors?
Then you better off to choose what we called some kind of "scaled" integer. Behind the scenes, the computer does NOT use floating numbers, but uses a integer value, and the also has a "decimal" position.
In fact, in a lot of older business BASIC languages, or others? We often had to do the scaling on our own. (so, we would choose a large integer format). In fact, this "scaling" feature still exists in Access!!! (and you see it in the format options).
So, two choices here. If you don't want "tiny" rounding errors, then use "currency" data type. This may, or may not be sufficient for you, since it only allows a max of 4 decimal places. But in most cases, it should suffice. And if you need "more" decimal places, then you can multiply the values by 1000, and then divide by 1000 when done the calculations.
however, try changing the column type to currency and that should work. (this type of data is how your desktop calculator also works - and thus you not see funny rounding errors as a result (in most cases).
but, the FIRST rule of the day? First computer course?
Computers do not store exact numbers for floating point numbers - they are approximations, and are subject to rounding errors. Now, if you really are using double for the table, then I don't think these rounding errors should show up - since you have "so many decimal places" available.
But, I would try using currency data type - it is a scaled integer, or so called packed decimal.
You can ALSO choose to use a packed decimal in Access, and it supports out to 28 digits, and you can set the "scale" (the decimal point location). However, since you can't declare a decimal type in VBA, then I would suggest that in the table (and in VBA code, use currency data types).
If you need more then 4 decimal points, then consider scaling the currency in your code, or perhaps at that point, you consider using a packed decimal type in the table, but values in VBA will have to use the "variant" type, and they will correctly take on the data column setting if used in code and assigned a value from the table(s) in question.
Needless to say, the first day you start dealing with computers, and that first day ANYTHING beyond being a "end user"? Well, this is your first lesson of the day!
"The data in both fields was updated with Round([Field01],2) and Round([Filed2],2) so the numbers in the fields should not be any longer than 2 decimal places." instead of rounding up(which i think is the reason for the scientific notation) you can use number field as data type , then under field size choose double, then under decimal places choose 2.
I have a timesheet application where people put eg. 3.5 hours worked in a day.
Sometimes someone might put 1.25 I guess.
I stored as float but am now having issues when I retrieve data... Should I have used decimal to 2 or 3 points?.
There are a few ways to tackle this.
If you want to have uniformity in the entries, I'd suggest using a "Fixed-Point Type" value (see more info here). This would mean that 3.5 hours should always be saved as 3.50.
The other option is to convert all your values to integer values (see more info here), and in your application layer, convert the values back to "readable" format. For example, you would store 1.25 hours as 125, and in your application layer, divide by 100, therefore getting 1.25. This method is more useful for currency management/calculation applications where a specific level of precision is necessary.
Floats allow for floating decimal point precision, so there is no restriction on uniformity of precision for decimal values...
For your purposes, I'd recommend fixed-point type unless there's complexity that you didn't mention.
Hope that helps.
I spotted some rounding bug in MySQL. Here is my query:
SELECT /*debugz*/ ROUND((SUM(grade)/2),0) AS grade, SUM(grade) FROM entry.computed_grade a WHERE a.stud_id='7901159' AND a.sy='2014' AND a.term=01 AND a.terms=01 AND a.catalog_no='Christian Life Formation';
and the result is this:
grade sum(grade)
------ ------------
92 185
The grade result should be 93, not 92 because 185/2 = 92.5
Try this
SELECT CEIL((SUM(grade)/2),0) AS grade, SUM(grade) FROM entry.computed_grade a WHERE ((a.stud_id='7901159') AND (a.sy='2014') AND (a.term=01) AND (a.terms=01) AND (a.catalog_no='Christian Life Formation'));
Try to use ceil instead of round.
e.g ceil(1.45) = 2
You should check rounding behavior artickle for mysql. I believe here is the reason of your problem:
For approximate-value numbers, the result depends on the C library. On
many systems, this means that ROUND() uses the “round to nearest even”
rule: A value with any fractional part is rounded to the nearest even
integer.
By the way it's IEEE standard for float point rounding, so you might want stay with it
Do not "patch" this problem by tweaking the query. Actually fix your database. If you are not storing the "grade" column as the DECIMAL data type, and are instead using FLOAT or DOUBLE, your design is inherently broken.
Because floating-point values are approximate and not stored as exact values, attempts to treat them as exact in comparisons may lead to problems.
http://dev.mysql.com/doc/refman/5.6/en/floating-point-types.html
This is not a bug in MySQL. It is an inherent limitation in industry-standard floating point number storage. Use DECIMAL columns to store meaningful, precise numbers, and the other two types only when low storage space or a wide range of allowable values are more important than precision.
Currently using MySQL version 5.1.6
This is my first real world build and so far I have actually been enjoying it; however, I now am stuck on a decision regarding a field datatype and hoping someone could sort it out for me.
I essentially have 10 fields that are all different test results. The numbers range from -100 to 100 and can have a decimal with one spot after the actual point.
For example, -5.1, 0, 1, 16.3, 99.2, and 100 are all possible data. From what I have read, one should use DECIMAL for those things that we usually measure and are exact (which these are), whereas FLOAT and DOUBLE are approximations, which I do not really want (though I am sure at this level, the approximation is very small if existent at all).
If I use DECIMAL, do I have to include a space for the '-' at the beginning if used? I.E, would I use DECIMAL(4,1) or DECIMAL(5,1) or am I way off here? I might be overthinking this a bit.
DECIMAL(4,1) will be enough, the sign digit does not need to be included.
More info: http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html
For example, a DECIMAL(3,0) column supports a range of -999 to 999
Decimal will be indeed the best option for your needs. Float and Double can give you ugly numbers (e.g. 0.2 cannot be represented as float, you'd get 0.19999999)
The negative symbol does NOT count as a digit in your calculation, so DECIMAL(4,1) should be fine.
Edit: That also seems like the right field to use for your purposes. Try it out!
Look at this query please
SELECT max( val_amd ) FROM `best_deposits`
I have the max value in the table equal to 14.6(the fields has type float),
But it returns 14.3599996566772
why does it happen, and how can i get the exact value?
Thanks much
floats are evil!
NEVER use floats for storing amounts or prices. instead of that, use an int and store the amount in cents. thats the only way to get around those problems forever.
why this happens: because floats can't be saved exactly in many cases (such as 0.6 in your case)
PS: we had those questions a hundret times for different languages till now:
Use Float or Decimal for Accounting Application Dollar Amount?
PHP rounding problem (5.2.3)?
Rounding problem with double type
Javascript rounding v c# rounding
Python rounding problem
... and a lot more
EDIT: to your comment: as i said:
use an int and store the amount in
cents
(alternatively you could use an DECIMAL(10,2) (or how big/how much decimal places you need)... not sure about how this works)
Or you better use "decimal" with length 10,2 or something like that for storing prices.