In my app I would like to randomize set values which I set in #define's. I am looking to use arc4random also. I usually would know how to do this but I have only seen tutorials with very basic things like numbers 0-10!
Any tips/help would be appreciated!
put all of your numbers to an array after that calculate an random number in range of 0 and sizeof your array. After you can get your randomized value from random place of predefined array and remove this value. Do it again for range 0 sizoef array - 1 and so on.
From the Wikipedia objective C article it looks like you can define macros using #define. From their example:
#define Add(x,y) ( x + y )
int a = 1;
int b = 2;
int c = Add(a,b);
NSLog(#"Add result: %i", c);
// this will output
// Add result: 3
I'm not sure how complex you can get with those, but I would think you'd be able to do something like #define MY_VAL() (arc4random()%100) to get a range of values, or maybe even use AlexTeho's idea within the macro.
Related
I am writing a Math Quiz app for my daughter in xcode/swift.Specifically, I want to produce a question that will contain at least one negative number to be added or subtracted against a second randomly generated number.Cannot be two positive numbers.
i.e.
What is (-45) subtract 12?
What is 23 Minus (-34)?
I am struggling to get the syntax right to generate the numbers, then decide if the said number will be a negative or positive.
Then the second issue is randomizing if the problem is to be addition or subtraction.
It's possible to solve this without repeated number drawing. The idea is to:
Draw a random number, positive or negative
If the number is negative: Draw another number from the same range and return the pair.
If the number is positive: Draw the second number from a range constrained to negative numbers.
Here's the implementation:
extension CountableClosedRange where Bound : SignedInteger {
/// A property that returns a random element from the range.
var random: Bound {
return Bound(arc4random_uniform(UInt32(count.toIntMax())).toIntMax()) + lowerBound
}
/// A pair of random elements where always one element is negative.
var randomPair: (Bound, Bound) {
let first = random
if first >= 0 {
return (first, (self.lowerBound ... -1).random)
}
return (first, random)
}
}
Now you can just write...
let pair = (-10 ... 100).randomPair
... and get a random tuple where one element is guaranteed to be negative.
Here's my attempt. Try running this in a playground, it should hopefully get you the result you want. I hope I've made something clean enough...
//: Playground - noun: a place where people can play
import Cocoa
let range = Range(uncheckedBounds: (-50, 50))
func generateRandomCouple() -> (a: Int, b: Int) {
// This function will generate a pair of random integers
// (a, b) such that at least a or b is negative.
var first, second: Int
repeat {
first = Int(arc4random_uniform(UInt32(range.upperBound - range.lowerBound))) - range.upperBound
second = Int(arc4random_uniform(UInt32(range.upperBound - range.lowerBound))) - range.upperBound
}
while (first > 0 && second > 0);
// Essentially this loops until at least one of the two is less than zero.
return (first, second)
}
let couple = generateRandomCouple();
print("What is \(couple.a) + (\(couple.b))")
// at this point, either of the variables is negative
// I don't think you can do it in the playground, but here you would read
// her input and the expected answer would, naturally, be:
print(couple.a + couple.b)
In any case, feel free to ask for clarifications. Good luck !
I'm currently parsing NSString values to NSNumbers and then adding them into a NSMutableArray called operands in an object called "data" like so:
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:*operandString];
[data.operands addObject:myNumber];
I then retrieve those numbers, perform some math on them, then update the array:
double x = [[data.operands objectAtIndex: i]doubleValue];
double y = [[data.operands objectAtIndex: i + 1]doubleValue];
double answer = x * y;
[data.operands replaceObjectAtIndex:(i) withObject:[NSNumber numberWithDouble:answer]];
When I get the answer, everything looks fine eg: ( 3.33 * 5 = 16.65)
BUT, when I look in the debugger I'm seeing some crazy values for x and answer, such as:
x = 3.3300000000000001
answer = 16.649999999999999
Why is this happening? Am I loosing some precision with parsing these back and fourth? Is it how I've used the NSNumberFormatter to parse the string?
The reason I'm in trouble with this is because I'm trying to ensure there's no double overflow errors so I'm using this simple test to check the integrity:
if (answer / y != x){
//THROW OVERFLOW ERROR
}
With the above crazy numbers this is always inconsistent. When I NSLog the answer it comes out fine:
NSLog (#"%g", [[data.operands objectAtIndex:i]doubleValue]]);
Same for
NSLog (#"%f", [[data.operands objectAtIndex:i]doubleValue]]);
You are not losing any precision that you need to worry about. Those are the correct values. There are only about 2^60 different double numbers, that finite set has to try to approximately cover the infinite 'number of numbers' in the range that doubles cover.
In other words, there are no exact answers in computer land and your
if (answer / y != x){
//THROW OVERFLOW ERROR
}
Will not work. Or it may work much of the time, but fail if you push it. Instead you need to acknowledge the limited precision (which is pretty high precision) of doubles:
//Don't waste time worrying like this...
if (fabs(answer / y - x) > 1e-12*fabs(answer)){
//Not correct or useful thing to check don't use this - i did not check
}
// let the math package handle it:
if (isnan(answer)){
// we gots problems
}
if (!isnormal(answer)){
// we gots some other problems
}
Also don't forget that 10^300 is a very large number, doubles work pretty well. To use 32 bit floats you need to pay much more attention to order of execution, etc.
NSLog is likely outputting with fewer decimals of precision, and rounds to the nearest thing, so the answers look better.
Let's say I have a number like 134658 and I want the 3rd digit (hundreds place) which is "6".
What's the shortest length code to get it in Objective-C?
This is my current code:
int theNumber = 204398234;
int theDigitPlace = 3;//hundreds place
int theDigit = (int)floorf((float)((10)*((((float)theNumber)/(pow(10, theDigitPlace)))-(floorf(((float)theNumber)/(pow(10, theDigitPlace)))))));
//Returns "2"
There are probably better solutions, but this one is slightly shorter:
int theNumber = 204398234;
int theDigitPlace = 3;//hundreds place
int theDigit = (theNumber/(int)(pow(10, theDigitPlace - 1))) % 10;
In your case, it divides the number by 100 to get 2043982 and then "extracts"
the last decimal digit with the "remainder operator" %.
Remark: The solution assumes that the result of pow(10, theDigitPlace - 1) is
exact. This works because double has about 16 significant decimal digits and int on iOS
is a 32-bit number and has at most 10 decimal digits.
How about good old C?
int theNumber = 204398234;
char output[20]; //Create a string bigger than any number we might get.
sprintf(output, "%d", theNumber);
int theDigit = output[strlen(output)-4]-'0'; //index is zero-based.
That's really only 2 executable lines.
Yours is only 1 line, but that's a nasty, hard-to-understand expression you've got there, and uses very slow transcendental math.
Note: Fixed to take the 3rd digit from the right instead of the 3rd from the left. (Thanks #Maddy for catching my mistake)
Another solution that uses integer math, and a single line of code:
int theNumber = 204398234;
int result = (theNumber/100) % 10;
This is likely the fastest solution proposed yet.
It shifts the hundreds place down into the 1s place, then uses modulo arithmetic to get rid of everything but the lowest-order decimal digit.
So I am working on a project using F# for some SVG line manipulations.
I thought it would be good to represent color an RGB value as a tuple (R,G,B). It just made sense to me. Well since my project involves generating SVG lines in a loop. I decided to have a color offset, conveniently also represented in a tuple (Roffset, Goffset, Boffset)
An offset in this case represents how much each line differs from the previous.
I got to a point where I needed to add the tuples. I thought since they were of the same dimensions and types, it would be fine. But apparently not. I also checked the MSDN on tuples, but I did not find anything about how to add them or combine them.
Here is what I tried. Bear in mind I tried to omit as much irrelevant code as possible since this is a long class definition with LOTS of members.
type lineSet ( 10+ params omitted ,count, colorOff :byte*byte*byte, color :byte*byte*byte ,strokeWid , strokeWidthOff ) =
member val Color = color with get, set
member val ColorOffset = colorOff with get, set
member val lineCount = count with get, set
interface DrawingInterfaces.IRepresentable_SVG with
member __.getSVGRepresenation() =
let mutable currentColor = __.Color
for i in 1..__.lineCount do
currentColor <- currentColor + __.ColorOffset
That last line of code is what I wanted to do. However, it appears you cannot add tuples directly.
I also need a way to clamp the result so it cannot go over 255, but I suspect a simple try with block will do the trick. OR I could let the params take a type int*int*int and just use an if to reset it back to 255 each time.
As I mentioned in the comments, the clamping function in your code does not actually work - you need to convert the numbers to integers before doing the addition (and then you can check if the integer is greater than 255). You can do something like this:
let addClamp (a:byte) (b:byte) =
let r = int a + int b
if r > 255 then 255uy else byte r
Also, if you work with colors, then it might make sense to define a custom color type rather than passing colors around as tuples. That way, you can also define + on colors (with clamping) and it will make your code simpler (but still, 10 constructor arguments is a bit scary, so I'd try to think if there is a way to simplify that a bit). A color type might look like this:
type Color(r:byte, g:byte, b:byte) =
static let addClamp (a:byte) (b:byte) =
let r = int a + int b
if r > 255 then 255uy else byte r
member x.R = r
member x.B = b
member x.G = g
static member (+) (c1:Color, c2:Color) =
Color(addClamp c1.R c2.R, addClamp c1.G c2.G,addClamp c1.B c2.B)
Using the type, you can then add colors pretty easily and do not have to add clamping each time you need to do that. For example:
Color(255uy, 0uy, 0uy) + Color(1uy, 0uy, 0uy)
But I still think you could make the code more readable and more composable by refactoring some of the visual properties (like stroke & color) to a separate type and then just pass that to LineSet. This way you won't have 10+ parameters to a constructor and your code will probably be more flexible too.
Here is a modified version of your code which I think is a bit nicer
let add3DbyteTuples (tuple1:byte*byte*byte , tuple2:byte*byte*byte) =
let inline intify (a,b,c) = int a,int b,int c
let inline tripleadd (a,b,c) (d,e,f) = a+d,b+e,c+f
let clamp a = if a > 255 then 255 else a
let R,G,B = tripleadd (intify tuple1) (intify tuple2)
clamp R,clamp G,clamp B
I'm building an app that allows the user to perform some calculations except the calculations result in numbers with lots of decimal digits. It's fine for me to see that kind of precision but I want to let the users be able to choose how many significant digits they want shown. I'm creating a result string using a double and using the %g format shown here:
NSString *resultString = [[NSString alloc] initWithFormat:#"%.14g", result];
I have created a stepper that the users can interact with and storing the number they have chosen in another double. My question is, how can insert that double where the 14 is to change the number of significant digits? Or is this even possible? Please comment if you need clarification.
Any field width or precision in a format can be replaced by an * to indicate a dynamic value which is supplied by an int argument.
For example:
double d = 1.0/7;
for(int i = 4; i < 12; i++)
NSLog(#"%.*g", i, d);
Outputs:
0.1429
0.14286
0.142857
0.1428571
0.14285714
0.142857143
0.1428571429
0.14285714286