I have a JsonArray with an entry like: [1502054710762,-93.787]
I am using the QDecimal class in my project to work with real decimal values instead of float or double.
Now my problem is, that the value in the JsonArray is not a string. It is a JsonNumber as decimal. If I try to read the value throuh array.at(1).toDouble(), I generate an inaccurate decimal value.
Interesting point: this only happens on my Linux server, but runs fine on my Notebook. - No idea why...
You can't use toDouble() to get it out as that changes the precision available. You're going to have to do your math with QDecimal.
Related
I can't believe I have never had this issue before (nor can I find anyone else with the same issue) but today I have just discovered that SAS sometimes gets simple calculations wrong!?! I noticed that one of my records wasn't getting picked up in the right group based on a value being <3.6 and thought there must be something strange in my data with decimal places. But on investigation I found it was just because SAS was calculating the value wrong! For some reason that I can't fathom, it seems that SAS calculates 90 - 86.4 as 3.59999999999999!!! Simple program below to show this:
code
output
If I alter the calculation to 10 - 6.4 I get the correct value of 3.6000 but for some reason this one is coming out wrong. Could there be some mad setting that is wrong in my installation? I tried both SAS EG and Base SAS and both have the same issue. I feel like I'm going mad! Any help appreciated.
Thanks.
Floating point arithmetic, in any language, will have this same issue. The same issue is possible to understand in human terms, assuming the human doesn't have a concept of infinite. If you only write down 4 digits for your decimals, for example, then:
1 - (1/3) - (1/3) - (1/3)
That's zero, right?
1 - 0.3333 = 0.6667
0.6667 - 0.3333 = 0.3334
0.3334 - 0.3333 = 0.0001
Nope! Computers do the same thing, but in binary, so they have a different (and larger) set of "problem" numbers. 1/10, for example, is not representable in binary - so adding or subtracting 0.1 is not always a "neat" operation like it is in decimal.
SAS uses 8 byte floating points, and so it gets ~15 digits of accuracy. Assuming you're not working in a field where 15 digits of accuracy is needed, you should simply round.
if round(value,.01) ge 3.6 then ... ;
Most of the time this isn't needed, but strictly speaking you should always compare rounded numbers whenever using floating point numbers (as SAS does). Integers are safe, but if you're working with 0.1 etc., use ROUND or FUZZ for integers.
Sorry Cannot replicate your findings.
data x;
a=90-86.4;
run;
Gives the correct result. Are you using any formats or put function. Share the complete code.
I have problem with conversion from binary to decimal value.
I keep every bit of binary number in the another cell so I'm looking for some tip how to connect that number into one row using some automatic function and then use BIN2DEC function.
On the picture I wanted to show you what I want to do.
Use something like "=BIN2DEC(CONCATENATE(A1;B1;C1;D1;E1;F1;G1;H1))" to achieve the desired decimal value.
I' making a financial c++ application that uses postrgresql and fixed decimal data type.
I searched for a good implementation of fixed decimal, but i only find fixed binary or floating decimal.
I need to get and set pg fields, but i can't understand how to create a numeric data, do some addiction and subtraction, put it in a pg field and get it back.
I find only examples on floating decimal, but i need to use fixed decimal, cobol style, like nnnnnnnn.mm.
what i'm searching is like:
decimal a(6,2);
decimal b(6,2);
a=22222.55;
b=22222.66;
a=add(a,b);
pqxx.setfield(1,b);
There is something useful for this?
I'm saving data to a PostgreSQL backend through Django. Many of the fields in my models are DecimalFields set to arbitrarily high max_digits and decimal_places, corresponding to numeric columns in the database backend. The data in each column have a precision (or number of decimal places) that is not known a priori, and each datum in a given column need not have the same precision.
For example, arguments to a model may look like:
{'dist': Decimal("94.3"), 'dist_e': Decimal("1.2")}
{'dist': Decimal("117"), 'dist_e': Decimal("4")}
where the keys are database column names.
Upon output, I need to preserve and redisplay those data with the precision with which they were read in. In other words, after the database is queried, the displayed data need to look exactly like the data in that were read in, with no additional or missing trailing 0's in the decimals. When queried, however, either in a django shell or in the admin interface, all of the DecimalField data come back with many trailing 0's.
I have seen similar questions answered for money values, where the precision (2 decimal places) is both known and the same for all data in a given column. However, how might one best preserve the exact precision represented by Decimal values in Django and numeric values in PostgreSQL when the precision is not the same and not known beforehand?
EDIT:
Possibly an additional useful piece of information: When viewing the table to which the data are saved in a Django dbshell, the many trailing 0's are also present. The python Decimal value is apparently converted to the maximum precision value specified in the models.py file upon being saved to the PostgreSQL backend.
If you need perfect parity forwards and backwards, you'll need to use a CharField. Any number-based database field is going to interact with your data muxing it in some way or another. Now, I know you mentioned not being able to know the digit length of the data points, and a CharField requires some length. You can either set it arbitrarily high (1000, 2000, etc) or I suppose you could use a TextField, instead.
However, with either approach, you're going to be wasting a lot database resources in most scenarios. I would suggest modifying your approach such that extra zeros at the end don't matter (for display purpose you could always chop them off), or such that the precision is not longer arbitrary.
Since I asked this question awhile ago and the answer remains the same, I'll share what I found should it be helpful to anyone in a similar position. Django doesn't have the ability to take advantage of the PostgreSQL Numerical column type with arbitrary precision. In order to preserve the display precision of data I upload to my database, and in order to be able to perform mathematical calculations on values obtained from database queries without first recasting strings into python Decimal types, I opted to add an extra precision column for every numerical column in the database.
The precision value is an integer indicating how many digits after the decimal point are required. The datum 4.350 is assigned a value of 3 in its corresponding precision column. Normally displayed integers (e.g. 2531) have a precision entry of 0. However, large integers reported in scientific notation are assigned a negative integer to preserve their display precision. The value 4.320E+33, for example, gets the precision entry -3. The database recognizes that all objects with negative precision values should be re-displayed in scientific notation.
This solution adds some complexity to the structure and code surrounding the database, but it has proven effective. It also allows me to accurately preserve precision through calculations like converting to/from log and linear values.
I am curious which one would be better fitting as a currency field ? I will do simple operations such as taking difference, the percentage between old and new prices. I plan to keep two digits after the zero (ie 10.50) and majority of the time if these digits are zero, I will be hiding these numbers and display it as "10"
ps: Currency is NOT dollar based :)
Always use DecimalField for money. Even simple operations (addition, subtraction) are not immune to float rounding issues:
>>> 10.50 - 0.20
10.300000000000001
>>> Decimal('10.50') - Decimal('0.20')
Decimal('10.30')
The answer to the question is correct, however some users will stumble on this question to find out the difference between the DecimalField and the FloatField. The float rounding issue Seth brings up is a problem for currency.
The Django Docs States
The FloatField class is sometimes mixed up with the DecimalField class. Although they both represent real numbers, they represent those numbers differently. FloatField uses Python’s float type internally, while DecimalField uses Python’s Decimal type.
Read more here.
Here are other differences between the two fields:
DecimalField:
DecimalFields must define a decimal_places and a max_digits attribute.
You get two free form validations included here from the above required attributes, e.g. if you set max_digits to 4, and you type in a decimal that is 4.00000 (5 digits), you will get this error: Ensure that there are no more than 4 digits in total.
You also get a similar form validation done for decimal places (which in most browsers will also validate on the front end using the step attribute on the input field. If you set decimal_places = 1 and type in 0.001 as the value you will get an error that the minimum value has to be 0.1.
Returns a decimal.Decimal, type is <class 'decimal.Decimal'>
Does not have the extra validation of DecimalField
With a Decimal type, rounding is also handled for you due to the required attributes that need to be set as described above. So from the shell, if you
In the database (postgresql), the DecimalField is saved as a numeric(max_digits, decimal_places) Type, and Storage is set as "main", from above example the Type is numeric(4,1)
More on DecimalField from the Django Docs.
FloatField:
Returns the built in float type, <type 'float'>
No smart rounding, and can actually result in rounding issues as described in Seths answer.
Does not have the extra form validation that you get from DecimalField
In the database (postgresql), the FloatField is saved as a "double precision" Type, and Storage is set as "plain"
More on FloatField from the Django Docs.
Applies to Both:
Both fields extend from the Field class and can accept blank, null, verbose_name, name, primary_key, max_length, unique, db_index, rel, default, editable, serialize, unique_for_date, unique_for_month, unique_for_year, choices, help_text, db_column, db_tablespace, auto_created, validators, error_messages attributes, as all Fields that extend from Field would have.
The default form widget for both fields is a TextInput.
I came across this question when looking for the difference between the two fields so I think this will help those in the same situation :)
UPDATE: To answer the question, I think you can get away with either to represent currency, although Decimal is a much better fit. There is a rounding issue when it counts to float's so you have to use round(value, 2) in order to keep your float representation rounded to two decimal places. Here is a quick example:
>>> round(1.13 * 50 + .01, 2)
56.51
You can still get in trouble with float and round. Like here we see it rounds down on a value of 5:
>>> round(5.685, 2)
5.68
But in this case, it will round up:
>>> round(2.995, 2)
3.0
It has all to do with how the float is stored in memory. See here.
I know this is super old, but I stumbled on it looking for something completely different, and I wanted to throw out there that in general it is inadvisable to use floating point numbers (float or decimal) for currency, as floating point math rounding will invariably lead to small errors in calculation that can add up to very large discrepancies over time.
Instead, use an integer field or a string at your preference. Multiply your currency to move the decimal place to the end and make a whole number when you store it, and then move that decimal place back where it belongs when you need to show it. This is basically how banks (and most currency libraries) handle storing data and will save you loads of trouble later on.
I learned this the hard way because it's not really a common topic; maybe this saves someone else from doing the same thing.
edit: The Satchmo Project is no longer active, so take a look at these alternatives for handling currency
Django Money
Oscar
The Django-based Satchmo Project has a CurrencyField and CurrencyWidget that are worth taking a look at.
Check out the satchmo_utils app directory for the source