Objc: convert unsigned long to float [duplicate] - objective-c

It might be a simple solution but I can not fix it.
I am dividing 2 integers :
finishedGameFinalScore = [score integerValue];
CGFloat interval = 2/finishedGameFinalScore;
NSLog(#"interval = %f",interval);
The log returns 0.000000
Is there a limit for decimal places? I need to preserve the decimal result.
Thanks
Shani

The reason your code doesn't work is that you're dividing an integer by another integer and then casting the result to a float.
So you have 2 (an integer) and some other number (also an integer). Then you divide 2 by this number - which is probably greater than 2. Let's say it's 3.
Integer sees 2/3 and he's like "0.66666667? Pshh, no one ever needs anything after the decimal point anyway". So he truncates it. You just have 0.
Then Integer gives the number to Mr. float and Mr float is super happy to get a number! He's all like "yay, a 0! I'm going to add ALL OF THE SIGNIFICANT DIGITS". And that's how you end up with 0.0000000.
So yeah, just cast to a float first. Or even a double!

#Dustin said u will need to typecast your divider value to float as it goes in float it shows integer value
CASE 1: Typecast
NSString *score = #"3";
int interval = [str intValue];
CGFloat interval = (2/(float)interval);
NSLog(#"interval = %.2f",interval);
CASE 2: No need for typecast
NSString *score = #"3";
float interval = [str floatValue];
CGFloat interval = (2/interval);
NSLog(#"interval = %.2f",interval);

Just add the f-hint to the number 2. in this case that will do the trick.
CGFloat interval = 2.0f/finishedGameFinalScore;
all the above/below answers are correct and fully explain why this work.

just devide long value from 1.0 and assigned to float variable.
unsigned long l1 = 65536;
unsigned long l2 = 256;
float f = (l1/1.0)/(l2/1.0);
NSLog(#"%f",f);

Related

NSString to int loses precision

I have a text string that represents a certain value without floating point number:
NSString *value1 = #"20141014135017";
NSString *value2 = #"20141014131024";
int one = [value1 intValue];
int two = [value2 intValue];
Why the result of one and two is only 2147483647? How can I solve this problem?
It depends on the platform, but on a 32-bit platform the limit of int is +/- 2 billion (−2,147,483,648 to 2,147,483,647 to be precise).
Use long instead:
long one = [value1 longValue];
long two = [value2 longValue];
int values can only support a limited number of bits. You should use float or double.
Here is a more comprehensive text on integers link

Objective-C: Flooring to 3 decimals correctly

I am trying to floor a float value to the third decimal. For example, the value 2.56976 shall be 2.569 not 2.570. I searched and found answers like these:
floor double by decimal place
Such answers are not accurate. For example the code:
double value = (double)((unsigned int)(value * (double)placed)) / (double)placed
can return the value - 1 and this is not correct. The multiplication of value and placed value * (double)placed) could introduce something like: 2100.999999996. When changed to unsigned int, it becomes 2100 which is wrong (the correct value should be 2101). Other answers suffer from the same issue. In Java, you can use BigDecimal which saves all that hassels.
(Note: of course, rounding the 2100.9999 is not an option as it ruins the whole idea of flooring to "3 decimals correctly")
The following code should work:
#include <stdio.h>
#include <math.h>
int main(void) {
double value = 1.23456;
double val3;
val3 = floor(1000.0 * value + 0.0001) * 0.001; // add 0.0001 to "fix" binary representation problem
printf("val3 is %.8f; the error is %f\n", val3, 1.234 - val3);
}
this prints out
val3 is 1.23400000; the error is 0.000000
If there are any residual errors, it comes about from the fact that floating point numbers cannot necessarily be represented exactly - the idea behind BigDecimal and things like that is to work around that in a very explicit way (for example by representing a number as its digits, rather than a binary representation - it's less efficient, but maintains accuracy)
I had to consider a solution involving NSString and it worked like a charm. Here is the full method:
- (float) getFlooredPrice:(float) passedPrice {
NSString *floatPassedPriceString = [NSString stringWithFormat:#"%f", passedPrice];
NSArray *floatArray = [floatPassedPriceString componentsSeparatedByString:#"."];
NSString *fixedPart = [floatArray objectAtIndex:0];
NSString *decimalPart = #"";
if ([floatArray count] > 1) {
NSString *decimalPartWhole = [floatArray objectAtIndex:1];
if (decimalPartWhole.length > 3) {
decimalPart = [decimalPartWhole substringToIndex:3];
} else {
decimalPart = decimalPartWhole;
}
}
NSString *wholeNumber = [NSString stringWithFormat:#"%#.%#", fixedPart, decimalPart];
return [wholeNumber floatValue];
}
For example, the value 2.56976 shall be 2.569 not 2.570
Solution is has simple as that :
double result = floor(2.56976 * 1000.0) / 1000.0;
I don't know why you search complication... this works perfectly, doesn't need to pass by some unsigned int or other + 0.0001 or whatever.
Important note :
NSLog(#"%.4f", myDouble);
Actually do a round on your variable. So it's improper to believe you can floor with a %.Xf

double to int (or long, long long) conversion sometimes is not good

I am trying to convert quite big double number to int (or long or long long), but have some difficulties. Almost always it converts good, but not sometimes:
My code:
double price = 12345678.900000;
double hundredNumber = price * 100;
NSNumber *number = [NSNumber numberWithDouble:hundredNumber];
int tempNumber = [number intValue];
All goes good, until tempNumber. it logs out 1234567889, but it should be 1234567890 (...89 - ...90)
Does anyone know why it could happen and how to convert correctly?
P. S. I am trying to implement backspace to value (e.x. 123.45, after that it should be 12.34). Maybe anyone had implemented something like this?
You're always going to get the risk of rounding errors if you're using floating point numbers.
Why not always store prices as a long long?
i.e. instead of £5.50, store 550p. That way you will never have any rounding issues at all.
As commented, I would be careful with the roundings, because of the possible errors.
One possible solution is to work with doubles like Google does with coordinates in Android: multiplying them by 1E6. If you operate with integers then you'll safe much more CPU cycle than operating with doubles. Try this out:
double priceDouble = 33.f / 34.f;
NSLog(#"double: %f", priceDouble);
NSInteger priceInteger = (NSInteger)(priceDouble * 1E6);
NSLog(#"int: %d", priceInteger);
NSNumber * priceNumberWithDouble = [NSNumber numberWithDouble:priceInteger];
priceDouble = [priceNumberWithDouble doubleValue];
NSLog(#"double: %f", priceDouble);
NSNumber * priceNumberWithInteger = [NSNumber numberWithInteger:priceInteger];
priceInteger = [priceNumberWithInteger integerValue];
NSLog(#"int: %d", priceInteger);
double test = ((double)priceInteger)/1E6;
NSLog(#"Test: %f",test);
My output is the following:
double: 0.970588
int: 970588
double: 970588.000000
int: 970588
Test: 0.970588

Obtaining float from division between NSIntegers

I have two NSInteger variables called "domande" and "corrette". I have to execute this operation with them: corrette*10/domande. I want the result to be a float variable, so I declared a "voto" variable as so: "float voto = corrette*10/domande;" . When I output the value of "voto" with NSLog I get an approximated value of the result followed by ".000000".
Here's the code:
NSInteger domande = [numDomande integerValue];
NSInteger corrette = [numRisposteCorrette integerValue];
float voto = corrette*10/domande;
NSLog(#"float value is: %f", voto);
When I assign to "domande" a value of 7, and to "corrette" a value of 4: voto=5.000000
Instead it should be voto=5.71...
How can I have the division return not an integer type converted to float, but directly a float type?
Simplest way is to do:
float voto = 10.0f * corrette / domande;
By making the first argument a float, you guarantee that the others will be promoted as well and that intermediate and final results will not suffer truncation.
You could achieve a similar result by casting corrette to a float but I tend to prefer simplicity where possible.
Rather than converting integers to floats, you could just get floats in the first place:
CGFloat domandeFloat = [numDomande floatValue];
CGFloat corretteFloat = [numRisposteCorrette floatValue];
CGFloat voto = (corretteFloat / domandeFloat) * 10.0f
NSLog(#"float value is: %f", voto);
NSInteger does not have a method called floatValue. NSInteger is just an int. Instead, the solution would be:
CGFloat domandeFloat = [[NSNumber numberWithInt: numDomande] floatValue];
CGFloat domandeFloat = [[NSNumber numberWithInt: numRisposteCorrette] floatValue];
CGFloat voto = (corretteFloat / domandeFloat) * 10.0f;
Try to convert the NSIntegers to a float type first:
float voto = (float)corrette*10/(float)domande;
you can cast "10" from int to float by writing it as "10.0"
float voto = corrette*10.0/domande;
or
float voto = ((float)corrette*10) / (float)domande;
Operation "/" is returning type of it operands - 5/4 will return int result 1 because 5 and 4 are int, and 5.0/4.0 will return 1.25, because 5.0 and 4.0 are interpreted as float values. So you should manually cast type of input variables corrette and domande to float

How to round an float value and convert it into NSInteger value in the iPhone SDK?

I need to round a float value and convert it into an NSInteger value.
For example:
float f = 90.909088;
I want the result to be 91. How to get rid of this?
A quick round and cast will work for negative values as well as positives:
NSInteger intValue = (NSInteger) roundf(f);
One of the following C math functions might work for you:
double ceil(double)
double floor(double)
double nearbyint(double)
double rint(double)
double round(double)
long int lrint(double)
long int lround(double)
long long int llrint(double)
long long int llround(double)
double trunc(double)
To get more documentation, open a terminal session and type (for example)
man lround
I pick lround as an example because I think that is the one you want.
Do
f = floor(f + 0.5)
before the integer conversion.
Try:
float f = 90.909088;
NSNumber *myNumber = [NSNumber numberWithDouble:(f+0.5)];
NSInteger myInt = [myNumber intValue];