Cannot add/subtract from large doubles in Objective C - objective-c

I am trying to subtract 1 from a double with this code:
-(NSMutableArray *)getMoreTwitterDataWithMaxID:(double)maxID {
double newestID = (maxID - 1);
NSLog(#"newest ID is %f and maxID is %f", newestID, maxID);
// other code
}
The console is spitting this out:
2012-05-15 11:21:14.693 nearYou[2570:3a03] newest ID is 202429657738522624.000000 and maxID is 202429657738522624.000000
I'm not sure why they aren't subtracting . . .
Any help greatly appreciated!

May be you have reached the limit of the double data type. You can use NSDecimal instead.

You may have reached the limits of the double floating point format. The 64-bit floating point format only has a 52-bit mantissa, meaning it can only hold an integer of 52 bits with any integer accuracy before it uses the exponent. Your number is larger than that so the gap between one integer and the next possible one has grown bigger than 1.

Related

How would i separate an answer in Kotlin do print 2 different types

Hi this is my first ever program I'm tryin to write in android studio/Kotlin and I'm not sure how to proceed.
so in my program i have a few math tasks to do and it does it fine but what I need to do now is separate part of the answer then covert it then print out both parts
for example if my answer was 1.5232 i would like to convert the decimal part of the answer to a string that matches a range if its in it. the ranges I have are in the .0000 area so I would like to limit the decimal range too.
so final result would look like this
1 (whatever my string in range is)
I hope I included enough info thank you in advance.
The first part of the task is to split the number into the integer and fractional components:
val input = 1.5232
val integer = input.toInt() // rounds DOWN to nearest smaller Int
val fractional = input % 1.0 // The remainder when dividing by 1.0 is the fraction
The strategy I would use to round to the nearest fractional value given a certain precision is to multiply by that precision, and round to the nearest integer. That would give you the numerator, and the precision would be the denominator:
val denominator = 8 // fractional precision
val numerator = (fractional * denominator).roundToInt() // rounds up or down to nearest Int
Then to put it together, you can use a string template:
val result = "$integer $numerator/$denominator"
println(result)
Simplifying the fraction would be another task if you need that. You can find various algorithms for finding greatest common divisor of two numbers. Use one of those and divide the numerator and denominator by that value.

comparing floats gives weird behaviour ( > operator)

I'm doing a simple comparison between two floating points. When logging however, I came across some unexpected behaviour of this rather basic code:
float balance = self.balance.floatValue;
float amount = self.amountTextField.text.floatValue;
if(amount > balance && self.amountTextField.text != nil){
allowTransfer = NO;
NSLog(#"allowtransfer: %u", allowTransfer);
}
In my testcase, I used balance as a floating point of 47.95.
All goes well with the comparison until i try 47.96 as a balance and still allowTransfer isn't called, all up to 48.00
Why is somehow the compiler not considering decimals?
Your problem is that you are casting both numbers to an int when comparing them, which will truncate both numbers and make it impossible to exactly compare them, it will only compare the integer parts.
To solve it just use float:
float balance = self.balance.floatValue;
float amount = self.amountTextField.text.floatValue;
Although when dealing with money, you should not use double or float. The reason is that they do not support arbitrary precision and you cannot represent exact values (for instance 0.1 + 0.2 as double is actually 0.30000000000000004
Have a look at NSDecimalNumber for arbitrary precision numbers.

Rounding issue when using NSString and %f [duplicate]

I have a floating point number that have more decimal digits, for example:
float fRes = 10.0 / 3.0;
actually the fRes value is 3.3333333333333
it's possible set for example 2 decimal digits:
float fRes = 10.0 / 3.0;
// fRes is 3.333333333333333333333333
float fResOk = FuncRound( fRes, 2 );
// fResOk is 3.33
thanks in advance
I don't know where you are using this rounded number, but you should only round your value when displaying it to the user, there are C based format string ways to round floating point numbers for example
[NSString stringWithFormat:#"%.2f", value];
as you may have already read, floating point number are approximations of real numbers, so doing fResOk = roundf( fRes*100.0)/100.0; may not give you 3.33 but a number which is just as close as you can get with floating point number to 3.33.
Assuming that you're looking for the correct function to round to a certain number of digits, you'll probably find it easiest to do the following:
fResOk = roundf( fRes*100.0)/100.0;
That will multiply the value by 100 (giving you your 2 digits of significance), round the value, and then reduce it back to the magnitude you originally started with.

Convert float representing hours to integer hours and minutes

I'm using the standard equation of distance / speed = arrival time. This works fine, but the answer is a float number and most people would find it awkward to convert something like 1.75 hrs to be 1 hr and 45 minutes.
I want to take that final float number result and extract the hour(s) separately from the minutes as integers.
Here is what I've tried:
-(IBAction)calculate:(id)sender {
float spd=[speed.text floatValue];
float dist=[distKnots.text floatValue];
//this give me the answer as a float
float arr=(dist/bs);
//this is how I showed it as an answer
//Here I need to convert "arr" and extract the hours & minutes as whole integers
arrivalTime.text=[NSString stringWithFormat:#"%0.02f", arr];
[speed resignFirstResponder];
}
And this is the conversion I tried to do -- and on paper it works, but in code it's full of errors:
int justHours = arr*60;
int justMinutes = (arr*60)-(justHours*60);
//then for the user friendly answer:
arrivalTime.text=[NSString stringWithFormat:#"%n hours and %n minutes", justHours, justMinutes];
I'm new to Objective-C and hoping there is a way to get this to work or a better way altogether to resolve this.
Your arr variable is already measured in hours, so you shouldn't be scaling it, just rounding it down:
int justHours = (int)arr;
and then your minutes is sixty times the (integer) difference between the original and rounded hours (i.e. the fractional part).
int justMinutes = (int)((arr - justHours) * 60);
The int justHours = arr/60; seems to be incorrect, it should be int justHours = arr;.
check the NSNumber numberFormater class. I believe you can wrap your float with time format and the return it to the user.

Objective-C: Strange calculation result

I am learning Objective-C and have completed a simple program and got an unexpected result. This program is just a multiplication table test... User inputs the number of iterations(test questions), then inputs answers. That after program displays the number of right and wrong answers, percentage and accepted/failed result.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(#"Welcome to multiplication table test");
int rightAnswers; //the sum of the right answers
int wrongAnswers; //the sum of wrong answers
int combinations; //the number of combinations#
NSLog(#"Please, input the number of test combinations");
scanf("%d",&combinations);
for(int i=0; i<combinations; ++i)
{
int firstInt=rand()%8+1;
int secondInt=rand()%8+1;
int result=firstInt*secondInt;
int answer;
NSLog(#"%d*%d=",firstInt,secondInt);
scanf("%d",&answer);
if(answer==result)
{
NSLog(#"Ok");
rightAnswers++;
}
else
{
NSLog(#"Error");
wrongAnswers++;
}
}
int percent=(100/combinations)*rightAnswers;
NSLog(#"Combinations passed: %d",combinations);
NSLog(#"Answered right: %d times",rightAnswers);
NSLog(#"Answered wrong: %d times",wrongAnswers);
NSLog(#"Completed %d percent",percent);
if(percent>=70)NSLog(#"accepted");
else
NSLog(#"failed");
[pool drain];
return 0;
}
Problem (strange result)
When I input 3 iterations and answer 'em right, i am not getting of 100% right. Getting only
99%. The same count I tried on my iPhone calculator.
100 / 3 = 33.3333333... percentage for one right answer (program displays 33%. The digits after mantissa getting cut off)
33.3333333... * 3=100%
Can someone explain me where I went wrong? Thanx.
This is a result of integer division. When you perform division between two integer types, the result is automatically rounded towards 0 to form an integer. So, integer division of (100 / 3) gives a result of 33, not 33.33.... When you multiply that by 3, you get 99. To fix this, you can force floating point division by changing 100 to 100.0. The .0 tells the compiler that it should use a floating point type instead of an integer, forcing floating point division. As a result, rounding will not occur after the division. However, 33.33... cannot be represented exactly by binary numbers. Because of this, you may still see incorrect results at times. Since you store the result as an integer, rounding down will still occur after the multiplication, which will make it more obvious. If you want to use an integer type, you should use the round function on the result:
int percent = round((100.0 / combinations) * rightAnswers);
This will cause the number to be rounded to the closest integer before converting it to an integer type. Alternately, you could use a floating point storage type and specify a certain number of decimal places to display:
float percent = (100.0 / combinations) * rightAnswers;
NSLog(#"Completed %.1f percent",percent); // Display result with 1 decimal place
Finally, since floating point math will still cause rounding for numbers that can't be represented in binary, I would suggest multiplying by rightAnswers before dividing by combinations. This will increase the chances that the result is representable. For example, 100/3=33.33... is not representable and will be rounded. If you multiply by 3 first, you get 300/3=100, which is representable and will not be rounded.
Ints are integers. They can't represent an arbitrary real number like 1/3. Even floating-point numbers, which can represent reals, won't have enough precision to represent an infinitely repeating decimal like 100/3. You'll either need to use an arbitrary-precision library, use a library that includes rationals as a data type, or just store as much precision as you need and round from there (e.g. make your integer unit hundredths-of-a-percent instead of a single percentage point).
You might want to implement some sort of rounding because 33.333....*3 = 99.99999%. 3/10 is an infinite decimal therefore you need some sort of rounding to occur (maybe at the 3rd decimal place) so that the answer comes out correct. I would say if (num*1000 % 10 >= 5) num += .01 or something along those lines multiply by 100 moves decimal 3 times and then mod returns the 3rd digit (could be zero). You also might only want to round at the end once you sum everything up to avoid errors.
EDIT: Didn't realize you were using integers numbers at the end threw me off, you might want to use double or float (floats are slightly inaccurate past 2 or 3 digits which is OK with what you want).
100/3 is 33. Integer mathematics here.