issue with a number float - ios

I have a problem with my float variable, i have to do some operation and then i have a final number what I saw is that some time the number is not correct, but just for a point for example when i have this number and i try to print it i don't give me back the same number:
float myNumber = 27589353.0f;
NSLog(#"My Number is %.2f", myNumber);
the result is: My Number is 27589352.00
I've tried to put the variable double but i have the same issue.

The problem is that floats do not have enough precision, as maddy said in the comments above.
And this code:
double myNumber = 27589353.0f;
NSLog(#"My Number is %.2f", myNumber);
Won't work either because the "f" qualifier on the constant forces the number to be a float, causes the loss of precision, then promotes the value to a double, once the damage is done.
This code however, will work correctly:
double myNumber = 27589353.0;
NSLog(#"My Number is %.2f", myNumber);
(Note that I'm assigning a floating point value with a decimal, but no final "f"

try like that it's work, you have to remove the 'f' as well
double myNumber = 27589353.0;
NSLog(#"My Number is %.2f", myNumber);

Related

Shortest way to get digit number from a value

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.

objective c float increment wrong value

I have a query regarding floating value increment in loop.
I have following code
float add = 1.02f;
float counter = 0.0f;
for (int i = 0; i < 20; i++) {
counter += add;
NSLog(#"%f",counter);
}
While executing this loop I am getting following result
1.020000
2.040000
3.060000
4.080000
5.100000
6.120000
7.140000
8.160000
9.180000
10.200001
11.220001
12.240002
13.260002
14.280003
15.300003
16.320004
17.340004
18.360004
19.380005
20.400005
Here is expected result
1.020000
2.040000
3.060000
4.080000
5.100000
6.120000
7.140000
8.160000
9.180000
10.200000
11.220000
12.240000
13.260000
14.280000
15.300000
16.320000
17.340000
18.360000
19.380000
20.400000
Why i am getting some floating point in loop without adding it.
I need to loop more then 1000 times. And I want the value in float variable.
Thanks in advance.
This happens because float cannot represent the values that you have with exact precision. There are two simple ways of fixing this:
Represent the number as 100 times the target value, and use integers - 1.02 becomes 102, 2.04 becomes 204, and so on.
Use NSDecimalNumber to represent your numbers - Unlike float, NSDecimalNumber can represent all your values with full precision.
Here is how to implement the first approach:
int add = 102;
int counter = 0;
for (int i = 0; i < 20; i++) {
counter += add;
NSLog(#"%d.%d", counter/100, counter%100);
}
Here is how to implement the second approach:
NSDecimalNumber add = [NSDecimalNumber decimalNumberWithString:#"1.02"];
NSDecimalNumber counter = [NSDecimalNumber zero];
for (int i = 0; i < 20; i++) {
counter = [counter decimalNumberByAdding:add];
NSLog(#"%#", counter);
}
Why i am getting some floating point in loop without adding it.
Because float is a binary type that doesn't represent decimal values exactly. Rather than trying to explain completely and correctly, let me point you to the well-known paper What Every Computer Scientist Should Know About Floating Point Arithmetic.
Floating point number representations in computers are approximations, they are not exact. Sometimes you end up trying to display a number that can't be exactly represented in the computer's floating point number implementation, so it gives you an approximation. Also you get small arithmetic errors from repeated multiplications, additions, etc. of floating point numbers. The best you can do is to use doubles, which have more precision than floats do. In special circumstances, you could also represent your data in a different format and just change how you display it to the user to fit what they expect. For example, when working with dollars and cents, you could just store a total as a number of cents (which would be only an integer) and then format it to be shown as dollars and cents correctly for the user. There's no floating point rounding issues happening then.
Floating point numbers use four bytes = 32 bits.
1 bit for sign
8 bits for exponent
23 bits for mantissa
Precision: The number of decimal digits precision is calculated via number_of_mantissa_bits * Log10(2). Thus ~7.2 and ~15.9 for single and double precision respectively.
That's why you start to see rounding errors on the 7th digit
Source link.

arc4random_uniform output issue

in iOS Objetive-C I am trying to get the number typed by the user in a text field to set the upper bounder of a random number generation function in C.
- (IBAction)pushTheButton2:(id)sender {
u_int32_t upperBound = (u_int32_t) textField3.text;
textField4.text = [NSString stringWithFormat:#"%d", arc4random_uniform(upperBound)];
}
The output is a giant number that makes no sense. To test if function works, if I hardcode the actual upper bound in the arc4random_uniform function, such as arc4random_uniform(5), then it works!
I figured this could be some kind of literal conversion, so I tried to make this work with u_int32_t but still not outputting the right range.
Can someone help? Thanks
You are currently taking the memory reference pointer of the text and using that as the upper bound.
Try doing something like this instead...
NSInteger upperBound = [textfield.text intValue];
This will convert the string into an int that you can then use in the arc random function.
To parse string to integer you should do:
NSInteger upperBound = [textfield.text integerValue];

Why is converting my float to an int making the number negative?

NSTimeInterval expirationTime = (secondsSinceUnixEpoch*1000)+120000;
expirationTime = ceil(expirationTime/2);
int expirationInt = (int)expirationTime;
NSLog(#"%d", expirationInt);
The log output is always negative, even though before I convert it to an int it's positive... I tried just multiplying it by -1 to make it positive again and it's just staying negative! I'm totally perplexed.... don't know much about C, am I just doing something silly??
The number (secondsSinceUnixEpoch*1000)+120000 looks to me like it's going to be way too large to fit in an int. Chances are the integer is overflowing and becoming negative.
Converting to long long is one solution. As you stated in a comment, you want to show a whole number for use in a URL. Just do this:
NSTimeInterval expirationTime = (secondsSinceUnixEpoch*1000)+120000;
expirationTime = ceil(expirationTime/2);
NSString *urlString = [NSString stringWithFormat:#"http://example.com?time=%.0f", expirationTime];
This will format the decimal number as a whole number.

Objective-C Double, Long Calculation

I am trying to calculate a long value divided by an integer to give me what I would expect to be a double, although the result I am getting is 0. The code I am using...
double daysByYear = daysSinceBirthdayToService/365;
NSLog(#"%d", daysByYear);
In this code, daysSinceBirthdayToService variable is a Long Double which can be NSLogged using the following code (long)daysSinceBirthdayToService
It is declaired in the header file as a property of
#property (nonatomic) NSInteger daysSinceBirthdayToService;
Can anybody help me out with this, thanks!
The issue is that / between two longs will do an integral division.
To force a floating point division at least one of the operands needs to be cast to double.
e.g.
double daysByYear = daysSinceBirthdayToService/(double)365;
or if you have a literal make that a double by adding a decimal point
double daysByYear = daysSinceBirthdayToService/365.0;
double daysByYear = daysSinceBirthdayToService/365.0;
Can it be that %d outputs decimal number not a double?

Resources