How do I make randomized floats? - ios

I currently have a line of code which creates random numbers 1-5, but how do I include decimals, 1.00-5.00?
stoptimer.text = String(arc4random_uniform(4)+1)

You can convert your Int to Double and use String(format:) method to format your string as desired:
stoptimer.text = String(format: "%.2f", Double(arc4random_uniform(5)+1))

Increase the range of your generated numbers from 100 to 500 and devide the resulting one by 100.
stoptimer.text = String((arc4random_uniform(400)+100) / 100)

Related

"%.2f" is rounding my number up instead of cutting

I have the following number
7.9775609756097534
and I'm using the code below to only show two decimals
let formatted = String(format: "Angle: %.2f", angle)
the problem is that the result is:
7.98
instead of
7.97
For cases such as yours we use NumberFormatter. It is a class designed to do what you need and more. For your case it should be enough to use the following:
let numberFormatter = NumberFormatter()
numberFormatter.roundingMode = .down
numberFormatter.minimumFractionDigits = 2
numberFormatter.maximumFractionDigits = 2
numberFormatter.string(from: 1.236)
This now locks fraction digits to be exactly 2. By increasing minimum fraction digits more "0" may be appended as in 0.10 may become 0.100. Maximum fraction digits will simply restrict up to what point the number will be displayed.
There are other options as well such as making 1234567.89 show as 1.234.567,89 which is really nice for users that are used to such formatting.
Alternatively, you can do bit string manipulation
let numberInFloat:Float = 7.9775609756097534
let numberInString: String = String(format: "%f", numberInFloat)
let numberParts = numberInString.components(separatedBy: ".")
print(String(format: "Output: %#.%#", String(numberParts[0]), String(numberParts[1].prefix(2))))
Output: 7.97

decimal place value not working in swift

I'm not really sure what I am doing wrong here. I have a double:
let distanceInMiles = distanceInMeters/1609.344 and the results are 2.99685063032388e-09
But I want to round the number to one decimal place, so I do this:
let miles = String(format: "%.1f", distanceInMiles)
But when I print it out miles = 0.0. The decimal place works but it turns my number into 0 instead of 2.9
2.99685063032388e-09 is not equal to 2.9, it is 0.00000000299685063032388
http://www.wolframalpha.com/input/?i=2.99685063032388e-09
There is actually a cool way to do this, using the exponent format specifier instead of float. (From this list https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html)
let miles = String(format: "%.1e", distanceInMiles)

How to round a double to the nearest hundredth in Swift?

I am making an app, which takes one number usually something like 10.00 or 100.00 and multiplies it by 0.15 or 0.20 and outputs it to a Label.
What ends up happening in some situations is the answer comes out to be 2.3234342, notice all the numbers after the decimal, which I don't want.
I want Swift automatically round up to the nearest hundredth or keep hundredth the same and then delete everything after the hundredth.
I want the code to automatically determine whether it will round up or keep the number the same.
You can use round() with a "scale factor" of 1000:
let x = 14.14910001
let y = round(1000.0 * x) / 1000.0
println(y)
May be it will help you.
someFloat+=0.005
label.Text = String(format: "a float number: %.02f ", someFloat))

Getting weird value in Double

Hello i made a "Clicker" as a first project while learning swift i have an automated timer that is supposed to remove some numbers from other numbers but sometimes i get values like 0.600000000000001 and i have no idea why.
Here is my "Attack" function that removes 0.2 from the Health of a zombie.
let fGruppenAttackTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("fGruppenAttackTime"), userInfo: nil, repeats: true)
func fGruppenAttackTime() {
zHealth -= 0.2
if zHealth <= 0 {
zHealth = zSize
pPengar += pPengarut
}
...
}
And here is my attackZ button that is supposed to remove 1 from the health of the zombie
#IBAction func attackZ(sender: UIButton) {
zHealth -= Double(pAttack)
fHunger -= 0.05
fGruppenHunger.progress = Float(fHunger / 100)
Actionlbl.text = ""
if zHealth <= 0 {
zHealth = zSize
pPengar += pPengarut
}
}
Lastly here are the variables value:
var zHealth = 10.0
var zSize = 10.0
var pAttack = 1
var pPengar = 0
var pPengarut = 1
When the timer is on and the function is running and i click the button i sometimes get weird values like 0.600000000000001 and if i set the 0.2 in the function to 0.25 i get 0.0999999999999996 sometimes. I wonder why this happens and what to do with it.
In trojanfoe's answer, he shares a link that describes the source of the problem regarding rounding of floating point numbers.
In terms of what to do, there are a number of approaches:
You can shift to integer types. For example, if your existing values can all be represented with a maximum of two decimal places, multiply those by 100 and then use Int types everywhere, excising the Double and Float representations from your code.
You can simply deal with the very small variations that Double type introduces. For example:
If displaying the results in the UI, use NumberFormatter to convert the Double value to a String using a specified number of decimal places.
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 0 // or you might use `2` here, too
formatter.numberStyle = .decimal
print(formatter.string(for: value)!)
By the way, the NSNumberFormatter enjoys another benefit, too, namely that it honors the localization settings for the user. For example, if the user lives in Germany, where the decimal place is represented with a , rather than a ., the NSNumberFormatter will use the user's native number formatting.
When testing to see if a number is equal to some value, rather than just using == operator, look at the difference between two values and seeing if they're within some permissible rounding threshold.
You can use Decimal/NSDecimalNumber, which doesn't suffer from rounding issues when dealing with decimals:
var value = Decimal(string: "1.0")!
value -= Decimal(string: "0.9")!
value -= Decimal(string: "0.1")!
Or:
var value = Decimal(1)
value -= Decimal(sign: .plus, exponent: -1, significand: 9)
value -= Decimal(sign: .plus, exponent: -1, significand: 1)
Or:
var value = Decimal(1)
value -= Decimal(9) / Decimal(10)
value -= Decimal(1) / Decimal(10)
Note, I explicitly avoid using any Double values such as Decimal(0.1) because creating a Decimal from a fractional Double only captures whatever imprecision Double entails, where as the three examples above avoid that entirely.
It's because of floating point rounding errors.
For further reading, see What Every Computer Scientist Should Know About Floating-Point Arithmetic.
Squeezing infinitely many real numbers into a finite number of bits
requires an approximate representation. Although there are infinitely
many integers, in most programs the result of integer computations can
be stored in 32 bits. In contrast, given any fixed number of bits,
most calculations with real numbers will produce quantities that
cannot be exactly represented using that many bits. Therefore the
result of a floating-point calculation must often be rounded in order
to fit back into its finite representation. This rounding error is the
characteristic feature of floating-point computation.

Round function doesn't work as expected

I'm trying round a Double value with two decimal places:
var x = 0.68999999999999995
var roundX = round(x * 100.0) / 100.0
println(roundX) // print 0.69
If print the value is correct.. but the var value isn't that i expect, continue 0.68999999999999995
I need the Double value... not String like other StackOverflow answers :(
Floating point numbers like doubles do not have a number of decimal places. They store values in binary, and a value like .69 can't be represented exactly. It's just the nature of binary floating point on computers.
Use a number formatter, or use String(format:) as #KRUKUSA suggests
var x:Double = 0.68999999999999995
let stringWithTwoDecimals = String(format: "%.2f", x)
println(stringWithTwoDecimals)

Resources