arc4random_uniform producing very large values when casting to float - objective-c

Blank project. Code:
int i = 0;
while (i < 8) {
float amount = 100-arc4random_uniform(200);
NSLog(#"amount: %f", amount);
i++;
}
Log:
amount: 21.000000
amount: 90.000000
amount: 79.000000
amount: 4294967296.000000
amount: 39.000000
amount: 4294967296.000000
amount: 81.000000
amount: 4294967296.000000
4294967296.000000 is clearly outside the range of 100 - ran(200) (pseudocode)
If I don't declare amount as float and instead use int this doesn't happen.
What's going on here?

As #rob points out, arc4random_uniform returns a 32-bit unsigned integer type (uint32_t), that is, a number greater than or equal to zero, never negative. The compiler thus evaluates the expression 100-arc4random_uniform(200) expecting the result also to be an unsigned number.
If the result of arc4random_uniform(200) in your example code happens to be greater than 100, then 100-arc4random_uniform(200) will result in a negative number being assigned to a data type that cannot express negative numbers, so you'll end up with unexpected results.
You can indicate to the compiler that you want to be dealing with signed numbers by, as #rob suggests, casting the result of arc4random_uniform to a signed number (in this case a float):
float amount = 100 - (float)arc4random_uniform(200);
...or by indicating that the expression should return a signed number by explicitly making your other argument a signed number:
float amount = 100.0f - arc4random_uniform(200);

Related

Input out of range for Int datatype, not passing a testcase

I am trying to solve the following question on LeetCode; Write a function that takes an unsigned integer and returns the number of '1' bits it has. Constraints: The input must be a binary string of length 32.
I have written the following code for that which works fine for inputs 00000000000000000000000000001011 and 00000000000000000000000010000000 (provided internally by the website) but give output 0 for input 11111111111111111111111111111101 and in my local compiler for the last input it says "out of range"
class Solution {
// you need treat n as an unsigned value
fun hammingWeight(n:Int):Int {
var num = n
var setCountBit = 0
while (num > 0) {
setCountBit++
num= num and num-1
}
return setCountBit
}
}
To correctly convert binary string to Int and avoid "out of range error", you need to do the following (I believe LeetCode does the same under the hood):
fun binaryStringToInt(s: String): Int = s.toUInt(radix = 2).toInt()
"11111111111111111111111111111101" is equivalent to 4294967293. This is greater than Int.MAX_VALUE, so it will be represented as negative number after .toInt() convertion (-3 in this case).
Actually, this problem could be solved with one-liner in Kotlin 1.4:
fun hammingWeight(n: Int): Int = n.countOneBits()
But LeetCode uses Kotlin 1.3.10, so you need to adjust your solution to handle negative Ints as well.
Please change the type of your input variable from Int to a type like Double .At the moment The given value is bigger than the maximum value that a type Int number can store.

How to calculate the swap (rollover) in mt5 in term of account currency

Backgound:
using mt5
"swap" (rollover) price is defined in points (0.00001/0.001) - 5-digit broker
account currency: USD
The question is: how to calculate the "swap value" in terms of acc. currency in mt5. With other words, how many cents i will paid for one day rollover?
Currently have this "mql5" script:
#include <Trade\SymbolInfo.mqh>
void OnStart() {
CSymbolInfo sym; // symbol informations object
sym.Name( ChartSymbol() ); // get the object for the current chart symbol
if( sym.SwapMode() == SYMBOL_SWAP_MODE_POINTS) {
double lot = 0.1;
double swapUSD_long = sym.SwapLong() * 0; // need help here
double swapUSD_short = sym.SwapShort() * 0; // need help here
PrintFormat(
"symbol: %s swap_long: %.2f swap_short: %.2f swapUSD_long: %.2f swapUSD_short: %.2f",
sym.Name(),
sym.SwapLong(),
sym.SwapShort(),
swapUSD_long,
swapUSD_short
);
}
}
When attaching the script to EURAUD, it prints to terminal:
symbol: EURAUD swap_long: -10.80 swap_short: 6.80 swapUSD_long: 0.00
swapUSD_short: 0.00
so: the rollover price is 6.8 points for the short position. How to convert it to USD with current rate? For this need:
find the pair with the acc currency (in this case need find AUDUSD)
get the rate of AUDUSD sym.Bid() or sym.Ask()
and ...
simply need some help ;)
If I understand right your question, you can use the TickValueProfit and TickValueLoss. If the swap to some direction is negative (you will pay) use the TickvalueLoss and when positive use TickValueProfit.
You can make a function for this like the next:
double swap_value_currency(double value_point, double tickprofit, double tickloss)
{
if( value_point == 0.0 ) { return(0.0); }
if( value_point < 0.0 ) {
return( val * tickloss );
}
return( value_point * tickprofit);
}
The swap_value_currency returns the swap value depending on winning or losing for one standard lot.
so your fragment of code can be:
if( sym.SwapMode() == SYMBOL_SWAP_MODE_POINTS)
{
double swval_long = swap_value_currency(sym.SwapLong(), sym.TickValueProfit(), sym.TickValueLoss());
double swval_short= swap_vallue_currency(sym.SwapShort(), sym.TickValueProfit(), sym.TickValueLoss() );
}
and because this is for one standard lot, you need multiply it with your lot size...

NSDecimalNumber to the power of NSDecimalNumber

I have two NSDecimalNumbers and I need to apply one to the power of the other, originally this code was using doubles and I could compute this with the pow() function like this:
double result = pow(value1, value2);
The problem I have is I am converting the code to use NSDecimalNumbers and although they include the method toThePowerOf, it only accepts int values. At the moment the only solution I have to this problem is to convert the NSDecimalNumbers Temporarily but this results in a loss of precision.
double value1 = [decimal1 doubleValue];
double value2 = [decimal2 doubleValue];
double result = pow(value1, value2);
NSDecimalNumber *decimalResult = [[NSDecimalNumber alloc] initWithDouble:result];
Is there a way I can do this computation with NSDecimalNumbers and not lose the precision?
I need this to work with non integer values for example:
value1 = 1.06
value2 = 0.0277777777
As Joe points out, if you want to do this for positive integer powers, you can use NSDecimalPower() on an NSDecimal struct derived from your NSDecimalNumber (I personally prefer working with the structs, for performance reasons).
For the more general case of working with negative integers and fractional values, I have some code that I've modified from Dave DeLong's DDMathParser library. He has since removed the NSDecimal portion of this library, but you can find the last commit for this support. I extended Dave's exponential support into the following function:
extern NSDecimal DDDecimalPower(NSDecimal d, NSDecimal power) {
NSDecimal r = DDDecimalOne();
NSDecimal zero = DDDecimalZero();
NSComparisonResult compareToZero = NSDecimalCompare(&zero, &power);
if (compareToZero == NSOrderedSame) {
return r;
}
if (DDDecimalIsInteger(power))
{
if (compareToZero == NSOrderedAscending)
{
// we can only use the NSDecimal function for positive integers
NSUInteger p = DDUIntegerFromDecimal(power);
NSDecimalPower(&r, &d, p, NSRoundBankers);
}
else
{
// For negative integers, we can take the inverse of the positive root
NSUInteger p = DDUIntegerFromDecimal(power);
p = -p;
NSDecimalPower(&r, &d, p, NSRoundBankers);
r = DDDecimalInverse(r);
}
} else {
// Check whether this is the inverse of an integer
NSDecimal inversePower = DDDecimalInverse(power);
NSDecimalRound(&inversePower, &inversePower, 34, NSRoundBankers); // Round to 34 digits to deal with cases like 1/3
if (DDDecimalIsInteger(inversePower))
{
r = DDDecimalNthRoot(d, inversePower);
}
else
{
double base = DDDoubleFromDecimal(d);
double p = DDDoubleFromDecimal(power);
double result = pow(base, p);
r = DDDecimalFromDouble(result);
}
}
return r;
}
This runs exact calculations on positive integer powers, negative integer powers, and fractional powers that map directly to roots. It still falls back on floating point calculations for fractional powers that don't cleanly fall into one of those bins, though.
Unfortunately, this requires a few of his other supporting functions to work. Therefore, I've uploaded my enhanced versions of his _DDDecimalFunctions.h and _DDDecimalFunctions.m that provide this functionality. They also include NSDecimal trigonometry, logarithm, and a few other functions. There are currently some issues with convergence on the tangent implementation, which is why I haven't finished a public post about this.
I came across the same problem recently and developed my own function to do exactly this. The function has will calculate any base to any power as long as it yields a real answer if it determines a real answer cannot be calculated it returns NSDecimalnumber.notANumber
I have posted my solution as an answer to the same question that I posted so here is the link.

Generate Random Numbers Between Two Numbers in Objective-C

I have two text boxes and user can input 2 positive integers (Using Objective-C). The goal is to return a random value between the two numbers.
I've used "man arc4random" and still can't quite wrap my head around it. I've came up with some code but it's buggy.
float lowerBound = lowerBoundNumber.text.floatValue;
float upperBound = upperBoundNumber.text.floatValue;
float rndValue;
//if lower bound is lowerbound < higherbound else switch the two around before randomizing.
if(lowerBound < upperBound)
{
rndValue = (((float)arc4random()/0x100000000)*((upperBound-lowerBound)+lowerBound));
}
else
{
rndValue = (((float)arc4random()/0x100000000)*((lowerBound-upperBound)+upperBound));
}
Right now if I put in the values 0 and 3 it seems to work just fine. However if I use the numbers 10 and 15 I can still get values as low as 1.0000000 or 2.000000 for "rndValue".
Do I need to elaborate my algorithm or do I need to change the way I use arc4random?
You could simply use integer values like this:
int lowerBound = ...
int upperBound = ...
int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);
Or if you mean you want to include float number between lowerBound and upperBound? If so please refer to this question: https://stackoverflow.com/a/4579457/1265516
The following code include the minimum AND MAXIMUM value as the random output number:
- (NSInteger)randomNumberBetween:(NSInteger)min maxNumber:(NSInteger)max
{
return min + arc4random_uniform((uint32_t)(max - min + 1));
}
Update:
I edited the answer by replacing arc4random() % upper_bound with arc4random_uniform(upper_bound) as #rmaddy suggested.
And here is the reference of arc4random_uniform for the details.
Update2:
I updated the answer by inserting a cast to uint32_t in arc4random_uniform() as #bicycle indicated.
-(int) generateRandomNumberWithlowerBound:(int)lowerBound
upperBound:(int)upperBound
{
int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);
return rndValue;
}
You should avoid clamping values with mod (%) if you can, because even if the pseudo-random number generator you're using (like arc4random) is good at providing uniformly distributed numbers in its full range, it may not provide uniformly distributed numbers within the restricted modulo range.
You also don't need to use a literal like 0x100000000 because there is a convenient constant available in stdint.h:
(float)arc4random() / UINT32_MAX
That will give you a random float in the interval [0,1]. Note that arc4random returns an integer in the interval [0, 2**32 - 1].
To move this into the interval you want, you just add your minimum value and multiply the random float by the size of your range:
lowerBound + ((float)arc4random() / UINT32_MAX) * (upperBound - lowerBound);
In the code you posted you're multiplying the random float by the whole mess (lowerBound + (upperBound - lowerBound)), which is actually just equal to upperBound. And that's why you're still getting results less than your intended lower bound.
Objective-C Function:
-(int)getRandomNumberBetween:(int)from to:(int)to
{
return (int)from + arc4random() % (to-from+1);
}
Swift:
func getRandomNumberBetween(_ from: Int, to: Int) -> Int
{
return Int(from) + arc4random() % (to - from + 1)
}
Call it anywhere by:
int OTP = [self getRandomNumberBetween:10 to:99];
NSLog(#"OTP IS %ld",(long)OTP);
NSLog(#"OTP IS %#",[NSString stringWithFormat #"%ld",(long)OTP]);
For Swift:
var OTP: Int = getRandomNumberBetween(10, to: 99)
In Swift:
let otp = Int(arc4random_uniform(6))
Try this.

How to test whether the square root of a number will be rational?

How can you test whether the square root of a number will be rational or not?
Is this even possible?
I need this because I need to work out whether to display a number as a surd or not in a maths app I'm developing at the moment.
For integer inputs, only the square roots of the square numbers are rationals. So your problem boils down to find if your number is a square number. Compare the question: What's a good algorithm to determine if an input is a perfect square?.
If you have rational numbers as inputs (that is, a number given as the ratio between two integer numbers), check that both divisor and dividend are perfect squares.
For floating-point values, there is probably no solution because you can't check if a number is rational with the truncated decimal representation.
From wikipedia: The square root of x is rational if and only if x is a rational number that can be represented as a ratio of two perfect squares.
So you need to find a rational approxmiation for your input number. So far the only algorithm I've nailed down that does this task is written in Saturn Assembler for the HP48 series of calculators.
After reading comments and the answers to another question I have since asked, I realised that the problem came from a floating point inaccuracy which meant that some values (eg 0.01) would fail the logical test at the end of the program. I have amended it to use NSDecimalNumber variables instead.
double num, originalnum, multiplier;
int a;
NSLog(#"Enter a number");
scanf("%lf", &num);
//keep a copy of the original number
originalnum = num;
//increases the number until it is an integer, and stores the amount of times it does it in a
for (a=1; fmod(num, 1) != 0 ; a++) {
num *= 10;
}
a--;
//when square-rooted the decimal points have to be added back in
multiplier = pow(10, (a/2));
if (fmod(originalnum, 1) != 0) {
multiplier = 10;
}
NSDecimalNumber *temp = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:sqrt(num)/multiplier] decimalValue]];
NSDecimalNumber *result = [temp decimalNumberByMultiplyingBy:temp];
NSDecimalNumber *originum = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:originalnum] decimalValue]];
if ((fmod(sqrt(num), 1) == 0) && ([result isEqualToNumber:originum])) {
NSLog(#"The square root of %g is %#", originalnum, temp);
}
else {
NSLog(#"The square root of this number is irrational");
}
If you're dealing with integers, note that a positive integer has a rational square root if and only if it has an integer square root, that is, if it is a perfect square. For information on testing for that, please see this amazing StackOverflow question.
On https://math.stackexchange.com/ there is the question What rational numbers have rational square roots? that yielded an answer from Jakube that states that for "...rational numbers, an answer is to determine if the numerator and denominator are integers raised to the power of 2."
Good ways to work out whether natural numbers are perfect squares depends on the natural numbers the function supports (and the computer programming language being used) and the memory available etc. Here are a set of useful links:
https://math.stackexchange.com/questions/3431150/is-there-a-way-to-check-if-an-integer-is-a-square
https://codereview.stackexchange.com/questions/204974/fastest-way-to-determine-if-a-number-is-perfect-square
Fastest way to determine if an integer's square root is an integer
Check if BigInteger is not a perfect square
I developed and tested a solution in Java that works well enough for me with a set of natural numbers. The gist of this is given below. This code depends on BigMath and is implemented in agdt-java-math albeit in a couple of different classes:
/**
* #param x The number to return the square root of (if the result is
* rational).
* #return The square root of x if that square root is rational and
* {#code null} otherwise.
*/
public static BigRational getSqrtRational(BigRational x) {
BigInteger[] numden = getNumeratorAndDenominator(x);
BigInteger nums = getPerfectSquareRoot(numden[0]);
if (nums != null) {
BigInteger dens = getPerfectSquareRoot(numden[1]);
if (dens != null) {
return BigRational.valueOf(nums).divide(BigRational.valueOf(dens));
}
}
return null;
}
/**
* #param x The value for which the numerator and denominator are returned.
* #return The numerator and denominator of {#code x}
*/
public static BigInteger[] getNumeratorAndDenominator(BigRational x) {
BigInteger[] r = new BigInteger[2];
r[0] = x.getNumeratorBigInteger();
r[1] = x.getDenominatorBigInteger();
if (Math_BigInteger.isDivisibleBy(r[0], r[1])) {
r[0] = r[0].divide(r[1]);
r[1] = BigInteger.ONE;
}
return r;
}
/**
* #param x The number to return the square root of if that is an integer.
* #return The square root of {#code x} if it is an integer and {#code null}
* otherwise.
*/
public static BigInteger getPerfectSquareRoot(BigInteger x) {
if (x.compareTo(BigInteger.ZERO) != 1) {
return null;
}
BigInteger xs = x.sqrt();
if (x.compareTo(xs.multiply(xs)) == 0) {
return xs;
}
return null;
}
Also as square of any rational is rational, no rational is the square root of an irrational. This is clear to me having read Yves answer to: Prove that the square root of any irrational number is irrational. So, dealing with the case of rational numbers is sufficient to answer this question for all real numbers.