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.
Related
I'm kind of new to DAX and I'm basically learning as I'm using it in my work. We are building reports in PowerBI and we have data model that gets data from Oracle database. So I'm using DAX to create measures in this data model.
I need to substract 2 numbers from each other. So I created simple measure which looked like this:
[MEASURE1] - [MEASURE2]
Whether it works or it doesn't depends on my Period filter which uses another table. I don't know how could period be related to any of this. So when I change filter to some values, I get normal number. However, when I switch it to different values, I get numbers like 2,27483058473905E-13.
Weird thing is that if I check those two measures that I'm subtracting, they have exactly the same numbers, so the difference should be 0.
I know this is not the best explanation, but it is impossible to describe entire data model here. So I'm just looking for some ideas what could possibly be causing this and what should I check.
I have literally no idea what could be causing this.
Floating point precision.
Either use fixed decimal data types, specify the format string of the measure, or wrap your measure in ROUND, e.g.:
Diff =
ROUND (
[Measure 1] - [Measure 2] ,
2
)
2,27483058473905E-13 is not a huge number, but as close as a decimal calculator can get to zero.
I have a huge CSV data file that generates 500,000+ rows and 70+ columns, running Excel queries over this much data causes my desktop to crash.
As an alternative i've managed to import the CSV into Access.
The majority of the data fields i need to review/consider within further calculations i've imported as "double" field type.
I guess the first question is should i use single rather than double? The values i am considering will only ever report to 2 decimal places.
Within the imported table i've created some new columns, as i need to validate that the sum of underlying values equals the totals reported.
A sum of 5 underlying columns (called SUMofService)
[Ancillary Costs] + [Incidental Costs] + [One-Off Costs] + [Ongoing Costs] + [Transaction Costs]
I've not reviewed all 500,000 rows, but this formula seems to be summing the values correctly.
Using this value i've then created a new column to compare this total to the total in the report
IIF([SUMofService] = [Total Service],"Match","No Match")
This also seems to work as expected, but there are instances where this field returns a false.
Looking at the underlying numbers in [SUMofService] and [TotalService] they match, so i am confused as to why i am seeing the false results.
Could anyone review what i've detailed, and perhaps provide a steer as to whether i've considered something incorrectly.
There are probably better ways to achieve what i'm trying to do, but i haven't really used Access since school and you forget quite a bit in 30 years!!
Any responses are much appreciated - i've googled this as much as i can, but not 100% what to ask, and some responses are so far beyond my level of thinking.
should I use single rather than double?
The values I am considering will only ever report to 2 decimal places.
Neither. Use Currency.
That will also provide correct results for:
IIF([SUMofService] = [Total Service],"Match","No Match")
Using Double or, indeed, Single will cause floating point errors - as in this classic example:
? 10.1 - 10.0
9.99999999999996E-02
' thus:
? 10.1 - 10.0 = 0.1
False
In Amazon Athena, I want to round a big number to output me as decimal precision 2.
For example, I have 1.4309491454947177E11 which is equivalent to 143094914549.47177, so I expect result to be 143094914549.47
I am doing
SELECT ROUND(1.4309491454947177E11, 2)
But it is giving me wrong output 1.43.
Any help would be much appreciated!!!
The output is correct it is converting it to 2 decimals and you can use it in any downstream. It is just displayed as exponential. Similar to the way you see in excel and when you click on excel cell it displays actual value.
If you want to see data in 2 digit format.Cast will work make sure no of digits in cast is more than actual value
select cast(Round(1.4309491454947177E11 ,2) as decimal(20,2))
How do you increase the floating point precision representation of tensorflow variables? I need this cause my network is large and data is complex, so I want to see any amount of improvement no matter how small. When I iterate through the training I occasionally print the mean error to the screen, and all I see is the same 6 digits - it works fine with less complex inputs. Note that tensorboard seems to have similar precision, I would be happy enough with a more precise tensorboard graph.
msquaredError=m_sqerror.eval(sessions=sess,feed_dict={input:ip, output=op,keep_prob:1.0})
print ("MSE: %9f"%msquaredError)
output:
MSE: 0.317513
desired output:
MSE: 0.317513223 ... and many more digits
Stoopid error.
print ("MSE: %9f"%msquaredError)
should be
print ("MSE: %.9f"%msquaredError)
I have one number which I need to find the ceiling and the floor value of (203,400) in order to use this number to create a weighted average. From this number I want: 200,000 and 210,000 so the code I was using that doesn't work is:
S1CovA_ceil = ceil(S1CovA,10000);
S1CovA_floor = floor(S1CovA,10000);
When I run this program, I get these errors:
ERROR 72-185: The CEIL function call has too many arguments.
ERROR 72-185: The FLOOR function call has too many arguments.
Does anybody know a way around this or different SAS code I could use?
CEIL and FLOOR only remove decimals - specifically rounding to integer value. If you want it rounded to (above/below) multiple of 10,000, you have to do it a bit more complicatedly:
S1CovA_ceil = ceil(s1covA/10000)*10000;
And the same for floor. Basically you have to divide it by the desired rounding level, round the rest with ceil/floor, and then multiply back.
Unfortunately, as far as I'm aware, SAS doesn't allow rounding in a particular direction except for straight integer rounding.
You can also use the round() function...
%LET ROUNDTO = 10000 ;
data xyz ;
S1CovA_ceil = round(S1CovA+(&ROUNDTO / 2),&ROUNDTO) ;
S1CovA_floor = round(S1CovA-(&ROUNDTO / 2),&ROUNDTO) ;
run ;
Try
S1CovA_ceil = ceil(S1CovA/10000)*10000;
S1CovA_floor = floor(S1CovA/10000)*10000;