Making a calculation in objective c - iphone

I need a variable a = 6700000^2 * (a - b) (2 + sinf(a)+ s inf(b)), where a and b are floats between -7 to 7. I need all the precision that floats can give me.
Which data type should a be? Is the sinf the proper function to get the best precision out of a and b? And should a and b be in radians or degrees?
Well I Made a mistake when I posted the expression, the correct expression is c=67000000^2*(a-b)(2+sinf(a)+sinf(b)) and my problem is with c ."a" and "b" are floats and they are passed to me as floats, they really are coordinates (latitude and longitude) so thats not my concern... My concern is when using sinf on them do I lose any precision? And which type should c be so I don't lose precision cause I'm using a long double variable d to store a sum of multiple different c variables and d is returned to me as being zero and it shouldn't (sould be about 1 or 2 )so I was gessing I was losing some precision when calculating the c parcels...I was using c as being a double...can it be that I am losing some precision when calculating c?
Thank you very much for your help.

I can't tell you whether float is good enough for your application. If you need more precision, use double, and then use sin() instead of sinf().
The standard trig functions take angles in radians, as you'll discover if you read the relevant documentation.

Instead of using float, you should use a double if you want no worries in regards to memory. Remember to then change sinf() to sin() and use radians.

If you want the best precision without rolling your own types, you should use double rather than float. In that case, you can just use sin(3). According to the man page, you should pass the argument in radians.

Related

convert from double to int in anylogic

I am trying to convert a double value to int and use it in the number of agents per arrival. I have a distribution but want it to round to the nearest integer. I looked up the anylogic math functions but the only one that makes sense is rint but that still returns a double.
you can do this:
(int) rint(yourVariable)
Another way is to use (int)floor(myDouble)) and (int)ceil(myDouble)) .
With these, you can decide if you want to round up or down (if the default rounding rules aren't to your liking)

Understanding the datatype Double

I am trying to write a program in C to get the percent of even numbers in an array. I am thinking of writing it using int datatype. But some one mentioned to me using double will be easier. I don't understand that. Can anyone guide me with it?
What does double datatype return?
Can the return statement be given as return (double)? What will that give?
Can double convert a real number to a percent? Eg: 0.5 to 50.0
The int datatype is, as the name would suggest, integers (or whole numbers). So you cannot represent a decimal like 0.5. A double is decimal number. So you can hold numbers like 0.5. Common practice is to store your percentage as a simple decimal number like 0.5 (using the double type). Then when you need to display nicely as 50.0%, just multiply by 100 before displaying.
Here's a useful link on C's basic datatypes: http://www.tutorialspoint.com/ansi_c/c_basic_datatypes.htm

fortran90 reading array with real numbers

I have a list of real data in a file. The real data looks like this..
25.935
25.550
24.274
29.936
23.122
27.360
28.154
24.320
28.613
27.601
29.948
29.367
I write fortran90 code to read this data into an array as below:
PROGRAM autocorr
implicit none
INTEGER, PARAMETER :: TRUN=4000,TCOR=1800
real,dimension(TRUN) :: angle
real :: temp, temp2, average1, average2
integer :: i, j, p, q, k, count1, t, count2
REAL, DIMENSION(0:TCOR) :: ACF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
open(100, file="fort.64",status="old")
do k = 1,TRUN
read(100,*) angle(k)
end do
Then, when I print again to see the values, I get
25.934999
25.549999
24.274000
29.936001
23.122000
27.360001
28.153999
24.320000
28.613001
27.601000
29.948000
29.367001
32.122002
33.818001
21.837000
29.283001
26.489000
24.010000
27.698000
30.799999
36.157001
29.034000
34.700001
26.058001
29.114000
24.177000
25.209000
25.820999
26.620001
29.761000
May I know why the values are now 6 decimal points?
How to avoid this effect so that it doesn't affect the calculation results?
Appreciate any help.
Thanks
You don't show the statement you use to write the values out again. I suspect, therefore, that you've used Fortran's list-directed output, something like this
write(output_unit,*) angle(k)
If you have done this you have surrendered the control of how many digits the program displays to the compiler. That's what the use of * in place of an explicit format means, the standard says that the compiler can use any reasonable representation of the number.
What you are seeing, therefore, is your numbers displayed with 8 sf which is about what single-precision floating-point numbers provide. If you wanted to display the numbers with only 3 digits after the decimal point you could write
write(output_unit,'(f8.3)') angle(k)
or some variation thereof.
You've declared angle to be of type real; unless you've overwritten the default with a compiler flag, this means that you are using single-precision IEEE754 floating-point numbers (on anything other than an exotic computer). Bear in mind too that most real (in the mathematical sense) numbers do not have an exact representation in floating-point and that the single-precision decimal approximation to the exact number 25.935 is likely to be 25.934999; the other numbers you print seem to be the floating-point approximations to the numbers your program reads.
If you really want to compute your results with a lower precision, then you are going to have to employ some clever programming techniques.

Objective C Issue With Rounding Float

I have an issue with rounding the result of a calculation to two decimal places.
It is a financial calculation and when the result involves half a penny I would expect the number to be rounded up but it is in fact being rounded down.
To replicate the issue:
float raw = 16.695;
NSLog(#"All DP: %f",raw);
NSLog(#"2 DP: %.2f",raw);
Returns:
All DP: 16.695000
2 DP: 16.69
Whereas I would expect to see:
All DP: 16.695000
2 DP: 16.70
Can anyone advise if this is by design or if (most likely) I am missing something and if there is anything I can do to get around it. It is vital that it rounds up in this scenario.
Thanks in advance,
Oli
Don't use floats for financial calculations!
There are values that floats cannot represent exactly. 16.695 is one of them. When you try to store that value in a float, you actually get the closest representable value. When you perform a series of operations on a float, you can lose precision, and then you lose accuracy. This leads to losing money.
Use an actual currency type, use NSDecimalNumber, or do all your calculations with ints that count the smallest unit you care about (i.e., 1050 is $10.50 in whole cents, or $1.050 if you want fractions of pennies).
As far as I am aware the NSLog() function only takes formatting arguments and makes no attempt to round.
You may be use to using a printf() style function that does support rounding.
I suggest using one of the many functions in math.h to round your value before output and only rely on NSLog() for formatting.
After seeing the comments
Use the C standard function family round(). roundf() for float, round() for double, and roundl() for long double. You can then cast the result to the integer type of your choice
you could try this:
- (void)testNSlogMethod {
float value = 16.695; //--16.70
value = value *100;
int mulitpler = round(value);
NSLog(#"%.2f",mulitpler/100.0f);
}

Getting double precision in fortran 90 using intel 11.1 compiler

I have a very large code that sets up and iteratively solves a system of non-linear partial differential equation, written in fortran. I need all variables to be double precision. In the additional module that I have written for the code, I declare all variables as the double precision type, but my module still uses variables from the old source code that are declared as type real. So my question is, what happens when a single-precision variable is multiplied by a double precision variable in fortran? Is the result double precision if the variable used to store the value is declared as double precision? And what if a double precision value is multiplied by a constant without the "D0" at the end? Can I just set a compiler option in Intel 11.1 to make all real/double precision/constants of double precision?
So my question is, what happens when a single-precision variable is multiplied by a double precision variable in fortran? The single precision is promote to double precision and the operation is done in double precision.
Is the result double precision if the variable used to store the value is declared as double precision? Not necessarily. The right-hand side is an expression that doesn't "know" about the precision of the variable on the left hand side, in to which it will be stored. If you have Double = SingleA * SingleB (using names to indicate the types), the calculation will be performed in single precision, then converted to double for storage. This will NOT gain extra precision for the calculation!
And what if a double precision value is multiplied by a constant without the "D0" at the end? This is just like the first question, the constant will be promoted to double precision and the calculation done in double precision. However, the constant is still single precision and even if you wrote down many digits as for a double-precision constant, the internal storage is single precision and cannot represent that accuracy. For example, DoubleVar * 3.14159265359 will be calculated in double precision, but will be something approximating DoubleVar * 3.14159 done in double precision.
If you want to have the compiler retain many digits in a constant, you must specific the precision of a constant. The Fortran 90 way to do this is to define your own real type with whatever precision that you need, e.g., to require at least 14 decimal digits:
integer, parameter :: DoubleReal_K = selected_real_kind (14)
real (DoubleReal_K) :: A
A = 5.0_DoubleReal_K
A = A * 3.14159265359_DoubleReal_K
The Fortran standard is very specific about this; other languages are like this, too, and it's really what you'd expect. If an expression contains an operation on two floating-point variables of different precisions, then the expression is of the type of the higher-precision operand. eg,
(real variable) + (double variable) -> (double)
(double variable)*(real variable) -> (double)
(double variable)*(real constant) -> (double)
etc.
Now, if you are storing the result in a lower-precision floating point variable, it'll get down-converted again. But if you are storing it in a variable of the higher precision, it'll maintain it's precision.
If there's any cases where you're concerned that a single-precision floating point variable is causing a problem, you can force it to be converted to double precision
using the DBLE() intrinsic:
DBLE(real variable) -> double
If you write numbers in the form 0.1D0 it will treat it as double precision number, otherwise if you write 0.1, the precision will be lost in the conversion.
Here is an example:
program main
implicit none
real(8) a,b,c
a=0.2D0
b=0.2
c=0.1*a
print *,a,b,c
end program
When compiled with
ifort main.f90
I get results:
0.200000000000000 0.200000002980232 2.000000029802322E-002
When compiled with
ifort -r8 main.f90
I get results:
0.200000000000000 0.200000000000000 2.000000000000000E-002
If you use the IBM XLF compiler, the equivalence is
xlf -qautodbl=dbl4 main.f90
Jonathan Dursi's answer is correct - the other part of your question was if there was a way to make all real variables double precision.
You can accomplish this with the ifort compiler by using the -i8 (for integers) and -r8 (for reals) options. I'm not sure if there is a way to force the compiler to interpret literals as double-precision without specifying them as such (e.g. by changing 3.14159265359 to 3.14159265359D0) - we ran into this issue a while back.