ios performing calculations with large numbers - ios

I am just multiplying two very big value in ios.
value 1 999999999999
value 2 99999
I am using the data type as double long i.e long long and this works for only too big values but not for small values like 10*23 something like that i get different answers example
10.0*111.5 actual value in calculator is 1115 but i wat i get is 1110
please help me and i also want to roundof my answer to 3places like %.3f

This is probably what you are doing
long long left = 111.5; //Not good! Will truncate to 111
long long right = 10.0; //10
long long result = left * right; //111 * 10 = 1110
This is what you should do
double left = 111.5;
double right = 10.0;
double result = left * right; //111.5 * 10.0 = 1115.0
If for some reason double is not enough you can go for long double.

Related

Uniswap Liquidity Calculation issue on Arbitrum Chain

According to the "Liqudity Math in uniswap v3", the liqudity of a position should be:
L = amt0 * (sqrt(upper) * sqrt(cprice)) / (sqrt(upper) - sqrt(cprice))
or
L = amt1 / (sqrt(cprice) - sqrt(lower))
I tried to calculate the liquidity of the below position on Arbitrum:
The nft token ID of the position is 69171, so I can get the liqudity by calling the contract(0xC36442b4a4522E871399CD717aBDD847Ab11FE88) on https://arbiscan.io
You can see it shows the liqudity is 50242219347523, and we can do more unit convertion:
Now I try to calcuate this number with the uniswap V3 math:
This is the output:
As we can see, the code output is very similar to the contract output, but if we look carefully, we will find the unit seems to be different. I know the unit of the contract ouput should be 'wei', but I don't know what the unit of the code results is. Can anybody help? Thanks.
I checked that position and pool. Best to query the current price from the pool's contract, for quick look the UI can be found at https://info.uniswap.org/#/arbitrum/pools/0x2f5e87c9312fa29aed5c179e456625d79015299c
The current price is shown as 11.9011 ETH per BTC, and there are 0.3122 BTC and 1.466 ETH in the pool. This gives:
price = 11.9011 * (1e18 / 1e8)
x = 0.3122 * 1e8
y = 1.466 * 1e18
The tick range of the position No. 69171 is 253300 to 259900. Use these values to calculate sp = sqrt(price) and the square roots of the price range boundaries, and from them, the liquidity:
sp = price ** 0.5
sa = 1.0001 ** (253300 // 2)
sb = 1.0001 ** (259900 // 2)
Lx = x * sp * sb / (sb - sp)
Ly = y / (sp - sa)
L = min(Lx, Ly)
The result Lx is 49905251975363.266 and Ly is 51071435112054.96. The Etherscan info shows liquidity L=50242219347523, in between these two values, which have a few % difference. A few % is an acceptable error given the imprecise input values used in this calculation; the UI shows the price and amount values in a rounded format.

How do I fix the error "subscript out of range" in QBASIC?

I'm trying to create a code that generates random numbers within the range 10-30 but making sure that no number is repeated. It shows "subscript out of range" on NumArray(Count) = Count when I run the code.
'Make an array of completely sorted numbers
FOR Count = 10 TO 30
NumArray(Count) = Count
NEXT Count
RANDOMIZE TIMER
FOR Count = 10 TO 30
Number = (RND * (31 - Count)) + 10
PRINT #1, NumArray(Number)
FOR Counter = Number TO 30 - Count
NumArray(Counter) = NumArray(Counter + 1)
NEXT Counter
NEXT Count
This isn't actually my code. Copied and pasted for my assignment.
It looks like you're missing some DIM statements.
Variables containing numbers have type SINGLE by default, so you might see something like FOR Counter = 18.726493 TO 20 because the RND function returns a number between 0 and 1, excluding 1, meaning you will be trying to use NumArray(18.726493) which will not work.
Arrays that are not explicitly declared can only have 11 items with an index from 0 to 10, but the range 10-30 requires you to store 21 items (30 - 10 + 1 = 21). You can also specify a custom upper and lower bound if it will make your code easier for you to understand. Add these lines before the first line in your code shown above:
DIM Number AS INTEGER
DIM NumArray(10 TO 30) AS INTEGER
This will ensure Number only contains integers (any fractional values are rounded to the nearest integer), and NumArray will work from NumArray(10) to NumArray(30), but you can't use NumArray(9), NumArray(8), NumArray(31), etc. The index must be in the range 10-30.
I think that should fix your code, but I don't know for certain since I don't fully understand how it is supposed to work. At the very least, it will fix the type and subscript problems in your code.
You need to declare the array:
'Make an array of completely sorted numbers
DIM NumArray(30) AS INTEGER
FOR Count = 10 TO 30
NumArray(Count) = Count
NEXT Count
RANDOMIZE TIMER
FOR Count = 10 TO 30
Number = (RND * (31 - Count)) + 10
PRINT #1, NumArray(Number)
FOR Counter = Number TO 30 - Count
NumArray(Counter) = NumArray(Counter + 1)
NEXT Counter
NEXT Count

Why don't these numbers add in Xcode Debugger?

I'm using the Xcode debugger, and these numbers don't seem to add. I was curious as to why :
(lldb) p height
(CGFloat) $R0 = 2.1815627849240522E-314
(lldb) p frame.size
(CGSize) $R1 = (width = 375, height = 1000)
(lldb) p frame.size.height
(CGFloat) $R2 = 1000
(lldb) p height + frame.size.height
(CGFloat) $R3 = 1000
I have 3 questions about this..
What is 2.1815627849240522E-314 ? What kind of number is that?
Is it possible to instantiate temporary variables in debugger like you would in Ruby console, Chrome console etc.? For example, let temp_x = 4 ?
Why does my $R3 return 1000 and not.. something bigger?
2.1815627849240522E-314 is essentially zero. 1000 + 0 = 1000.
Floating point numbers have two parts - mantissa and exponent (position of the decimal point). e-341 means "move the decimal point 341 places to the right"
Adding 1000 to that very very small number creates a number that would be equal
1000.000...(> 300 zeros here)...2181567849240522
Even double mantissa can't represent numbers like this (double can represent up to 17 decimal digits) so it takes only the more important numbers in the beginning.
I encourage you to read through What Every Programmer Should Know About Floating-Point Arithmetic

Get randomFloat Fails

Why does my method return values < 0.4 in some cases?
e.g. 0.225501
#define ARC4RANDOM_MAX 0x100000000
float myVar = [self randomFloat:0.4 to:2];
- (float)randomFloat:(int)from to:(int)to
{
return ((double)arc4random() / ARC4RANDOM_MAX) * (to - from) + from;
}
You are casting your parameters to integers (which in your case changes your range to between 0 and 2), change the parameters to be float.
- (float)randomFloat:(float)from to:(float)to
when dividing and using floats the precision of the decimals is sometimes lost. Maybe you can use a long with N fixed number of digits and place the decimal point before those digits. The other day I was getting strange results when adding (1 + (3/10))= should be 1.3 but I always had something like 1.29995 . Hope it helps

Rounding to specific value?

I need to round a number, let's say 543 to either the hundreds or the tens place. It could be either one, as it's part of a game and this stage can ask you to do one or the other.
So for example, it could ask, "Round number to nearest tens", and if the number was 543, they would have to enter in 540.
However, I don't see a function that you can specify target place value to round at. I know there's an easy solution, I just can't think of one right now.
From what I see, the round function rounds the last decimal place?
Thanks
To rounding to 100's place
NSInteger num=543;
NSInteger deci=num%100;//43
if(deci>49){
num=num-deci+100;//543-43+100 =600
}
else{
num=num-deci;//543-43=500
}
To round to 10's place
NSInteger num=543;
NSInteger deci=num%10;//3
if(deci>4){
num=num-deci+100;//543-3+10 =550
}
else{
num=num-deci;//543-3=540
}
EDIT:
Tried to merge the above in one:
NSInteger num=543;
NSInteger place=100; //rounding factor, 10 or 100 or even more.
NSInteger condition=place/2;
NSInteger deci=num%place;//43
if(deci>=condition){
num=num-deci+place;//543-43+100 =600.
}
else{
num=num-deci;//543-43=500
}
You may just use an algorithm in your code:
For example, lets say that you need to round up a number to hundred's place.
int c = 543
int k = c % 100
if k > 50
c = (c - k) + 100
else
c = c - k
To round numbers, you can use the modulus operator, %.
The modulus operator gives you the remainder after division.
So 543 % 10 = 3, and 543 % 100 = 43.
Example:
int place = 10;
int numToRound=543;
// Remainder is 3
int remainder = numToRound%place;
if(remainder>(place/2)) {
// Called if remainder is greater than 5. In this case, it is 3, so this line won't be called.
// Subtract the remainder, and round up by 10.
numToRound=(numToRound-remainder)+place;
}
else {
// Called if remainder is less than 5. In this case, 3 < 5, so it will be called.
// Subtract the remainder, leaving 540
numToRound=(numToRound-remainder);
}
// numToRound will output as 540
NSLog(#"%i", numToRound);
Edit: My original answer was submitted before it was ready, because I accidentally hit a key to submit it. Oops.

Resources