I've been having this odd error in a recent swift program of mine. It involves random occurrences, and to simulate this I assign an event 'odds,' then generate two random numbers (using these odds), and if the numbers are the same then the action occurs. But the program crashes, inexplicably, in the generation part. The only explanation I can think of is the overabundance of casting required, but I'm not sure why it only crashes once in a while. I'd appreciate any insight as to why the casting crashes and any suggestions for what to do to avoid such excessive casting.
My image shows the code and the error, and the code below is a generalization of my code.
Crash Error
let rand = [Int(arc4random_uniform(UInt32(someInt))), Int(arc4random_uniform(UInt32(someInt)))]
if (rand[0] == rand[1]) {
executeAction()
}
This occurs because your integer variable shootOdds, at some point, takes a negative value (or: less plausible, a value larger than 4,294,967,295), causing runtime error for cast to unsigned integer, UInt32(someInt). You can avoid this by making sure, prior to the let rand = ... row, that shootOdds >= 0 (or in your code example above, someInt >= 0), or that you number is not larger than the upper limit for UInt32.
Hence note that the error is not associated with the rand function, but specifically the negative integer cast to unsigned integer.
E.g., try the following example in your playground, to assert you get the same runtime error:
let a = -1
let b = UInt32(a)
Due to faulty code, my odds were increasing exponentially and eventually too large to be contained in UInt32... and thus the error. Thanks for the help!
Related
I'm writing a piece of code in Scala which folds over this range:
(BigInt("0") until BigInt("1000000000000")).foldLeft(...)(...)
The code itself runs perfectly if I make the range smaller, but the program execution ends with exit code 0 without even executing any of the operations within FoldLeft.
When I try some additional examples, these are the results:
val range1 = (BigInt("0") until BigInt("1000000000000"))
println(range1(take(1)))
Result: No output, Process finished with exit code 0
val range2 (BigInt("0") until BigInt("1000"))
println(range2(take(1)))
Result: NumericRange 0 to 0, Process finished with exit code 0
As you can see, the range glitches out even if it doesn't ever evaluate the upper bound of the range. How can this happen? Numeric Ranges appear to be defined in the documentation as being valid, but as soon as they are actually used they glitch out.
Furthermore, in debug mode (IntelliJ) range1 throws an IllegalArgumentException when it is examined in-memory, because its size cannot be evaluated. When I check the documentation it seems this is correct, as the size of NumericRanges is definied by an Int.
Does this mean numeric ranges are basically impossible to use on large ranges in Scala?
TL;DR
Tried: iterating over Scala ranges using the until and to keywords, using the datatypes long and BigInt, with the size of the range larger than Int.MaxValue
Expected: able to iterate over numeric ranges
Result: program terminates unexpectedly
EDIT: Additional context, I'm having trouble with getting Scala to throw exceptions in general. I'm not sure if this is a scala problem or an intellij problem at the moment.
This is indeed a bug of scala collection library (NumericRange). Just to explain what happens, when you try to take some amount of values in a range, the API is designed to check if the amount of elements in the new range are more than Int.MaxValue, then it throws the exception. Here:
// ...
val limit = num.fromInt(Int.MaxValue)
// ...
if (num.gt(t, limit)) throw new IllegalArgumentException("More than Int.MaxValue elements.")
else t
// ...
But the same exact thing is not checked when you're actually creating new ranges, and that's unpredictable for the developers.
I have been working to understand why I am getting the error messages shown in the attachment.
The bottom-most message that indicates a comma is needed makes no sense to me at all.
The other two messages may well be related to a problem with data types, but I cannot determine what data type rules I have violated.
Many thanks for your time and attention.
It's a few different errors cropping up, and the error about the separator is not really indicative of the problem.
SecondPartFraction is being declared twice. If those are meant to be two different variables, they should have two different names. If you simply wish to reassign a new value to SecondPartFraction, just drop the var off the second time you use it (as is has already been declared, you simply need to refer to it again).
Doubles and Ints can't be together for division, so that error is correct. If you want to get a Double result, just change the 16 to 16.0. Then the compiler won't complain.
The numbers you're getting are originating from a textfield too, which might cause some problems. If the user enters text into your textfields, instead of numbers, the app will crash since StepFirstPart and StepSecondPart are force unwrapped. You will probably want to do some kind of Optional Chaining to handle the case where the entry is not numeric.
In the last line, the label text is being set to an Int - in order to do this, you'll have to use string interpolation instead, since the text for a label must be a string rather than a number:
TotalNumRisers.text = "\(TotalRisers)"
Just one last quick note - in Swift, camel casing is standard for naming, so the first letter of every variable should be lowercase, then the others upper. So StepFirstPart would become stepFirstPart instead.
You create the same variable twice here e.x
var x = 0
var x = value + x
instead it should be
var x = 0
x = value + x // remove var from here
Hello I have a problem with my Swift code.
In my application some SKLabelNodes are supposed to have their y coordinate set to
CGRectGetMaxY(self.frame) - (nodes[i].frame.size.height / 2 + 30) * (i + 4)
Where
var i:Int = 0
is a counter.
It works perfectly fine if instead of (i + 4) I just give it a literal value e.g. 5 or even (i == 0? 4 : 5) (just to see on two consecutive integers if the formula is correct itself).
But when I go with any variable or constant or expression containing one, it displays an error "CGFloat is not convertible to Int". It seems completely illogical, because 4 is an integer and so is i and even (i + 4), in which case changing 4 to i shouldn't change the whole expression's type.
Can anyone explain why do I get this error and how can I possibly solve it?
Thanks in advance.
You have already explained and solved the matter perfectly. It's simply a matter of you accepting your own excellent explanation:
It works perfectly fine if ... I just give it a literal value ... But when I go with any variable or constant or expression containing one, it displays an error "CGFloat is not convertible to Int".
Correct. Numeric literals can be automatically coerced to another type, such as CGFloat. But variables cannot; you must coerce them, explicitly. To do so, initialize a new number, of the correct type, based on the old number.
So, this works automagically:
let f1 : CGFloat = 1.0
let f2 = f1 + 1
But here, you have to coerce:
let f1 : CGFloat = 1.0
let f2 = 1
let f3 = f1 + CGFloat(f2)
It's a pain, but it keeps you honest, I guess. Personally I agree with your frustration, as my discussion here will show: Swift numerics and CGFloat (CGPoint, CGRect, etc.) It is hard to believe that a modern language is expected to work with such clumsy numeric handling, especially when we are forced against our will to bang into the Core Graphics CGFloat type so frequently in real-life Cocoa programming. But that, it seems, is the deal. I keep hoping that Swift will change in this regard, but it hasn't happened so far. And there is a legitimate counterargument that implicit coercion, which is what we were doing in Objective-C, is dangerous (and indeed, things like the coming of 64-bit have already exposed the danger).
In iPhone (Xcode 4), using the function,
srandom(time(NULL));
both srand and srandom is giving this warning. But when running its working fine.
Why I am getting the warning in one of my class file? I have used that in other files, but no warning.
Warning: passing argument 1 of 'srand' makes integer from pointer
without a cast
However, using arc4random() can solve this problem. But in most example srand() is used in this way and nobody complains. Thats why I am confused.
Because srand is expecting an integer and time() is returning a pointer (from the looks of your particular error). Casting explicitly to an int will make it go away. Or perhaps reading the pointer to get the actual time value might be what you are looking for instead. Not 100% certain of time's return value here, but I'd double check to make sure it is indeed returning a tics value instead of a pointer to a time_t object that will remain mostly the same over time.
According to what I just read, it's supposed to return a time_t value, which when cast as an int, is the number of seconds elapsed since 1972ish. So not a pointer usually, but in your case it may be. Either way, add either a dereference and a cast, or just a cast if you can get it to return the time_t directly.
I am using the pow() function like this in my application:
float IValuePlusOne = (pow(2.25,120));
but it is reporting back an infinite value, instead of the correct result. I even tried the long long and long double data types but couldn't get them to produce the proper output.
Is there any other data type I need to use or do I need to make some other changes in my code?
As others have pointed out, you're losing precision and reducing the size of value you can represent by casting to a float. Running the following code:
double IValuePlusOne = pow(2.25,120.0);
NSLog(#"Test value: %f", IValuePlusOne);
on my iPhone gives the output:
Test value: 1827688475348373523156051712429585892114432.000000
which looks to be correct (1.827x10^42).
If you want to do calculations on values that a double can't hold, use NSDecimalNumber.