In Xcode /Objective-C for the iPhone.
I have a float with the value 0.00004876544. How would I get it to display to two decimal places after the first significant number?
For example, 0.00004876544 would read 0.000049.
I didn't run this through a compiler to double-check it, but here's the basic jist of the algorithm (converted from the answer to this question):
-(float) round:(float)num toSignificantFigures:(int)n {
if(num == 0) {
return 0;
}
double d = ceil(log10(num < 0 ? -num: num));
int power = n - (int) d;
double magnitude = pow(10, power);
long shifted = round(num*magnitude);
return shifted/magnitude;
}
The important thing to remember is that Objective-C is a superset of C, so anything that is valid in C is also valid in Objective-C. This method uses C functions defined in math.h.
Related
I need to calculate modulos with decimals that can be negative as well
for example: fmod( -5.2, 3 );
while mod() works with integers, and fmod() (or fmodf()) works well with decimals, fmod() returns wrong results with negative decimals:
ex:
double modulo = fmod (5.2, 3);
NSLog (#"==> %f", modulo);
==> 2.2 // This is correct !!
double modulo = fmod (-5.2, 3);
NSLog (#"==> %f", modulo);
==> -2.2 // This is wrong !! should be 0.8
Is there another mod() in the library or should i write my own decimal negative mod function ?
something like :
if (res = fmod(x,m) < 0) {
res+=m;
}
Thx !
-2.2 is correct and is also -5.2 mod 3. The fmod function is a C function (and therefore also Objective C), so you can find more detail about it by typing man fmod into terminal. When doing fmod it will preserve the sign of the value that you are moding. So to get the mod you want, you will need to check the sign (of either the result, or the value you are passing in) and if it is negative you will need to add the modulo base, in this case 3.
This is the definition of the fmod function:
double
fmod(double x, double y);
Specifically, the functions return the value x-i*y, for some integer i such that, if y is non-zero, the result has the same sign as x and magnitude less than the magnitude of y.
from the OS X man page.
For your purposes, you can do something like this:
#include <math.h>
float f_mod(float a, float n) {
return a - n * floor(a / n);
}
Of course, be careful to check n>0.
f_mod(-5.2f, 2.0f) = 0.8
f_mod(5.2f, 2.0f) = 2.2
Thank you so i ended up writing a wrapper... What i was hopping i could avoid. This works great for me, and, in my opinion, represents the correct mathematical definition of the modulo (not the C implementation). I am sure this function can be optimized,but for clarity i leave it this way:
//--
//-- Modulo
//--
double calcModulo ( double x, double m) {
double res = INFINITY;
if (m==0)
return res ;
double posMod, negMod, posM, posX;
posM = m < 0 ? -m:m;
posX = x < 0 ? -x:x;
posMod = fmod (posX, posM);
negMod = fmod (-posX,posM) + posM;
// pick up the correct res
if ( x >= 0 ){
if (m > 0) {
res = posMod;
} else {
res = -negMod;
}
}else{
if (m > 0) {
res= negMod;
} else{
res= -posMod;
}
}
return res;
}
I'm using a for-loop to determine whether the long double is an int. I have it set up that the for loop loops another long double that is between 2 and final^1/2. Final is a loop I have set up that is basically 2 to the power of 2-10 minus 1. I am then checking if final is an integer. My question is how can I get only the final values that are integers?
My explanation may have been a bit confusing so here is my entire loop code. BTW I am using long doubles because I plan on increasing these numbers very largely.
for (long double ld = 1; ld<10; ld++) {
long double final = powl(2, ld) - 1;
//Would return e.g. 1, 3, 7, 15, 31, 63...etc.
for (long double pD = 2; pD <= powl(final, 0.5); pD++) {
//Create new long double
long double newFinal = final / pD;
//Check if new long double is int
long int intPart = (long int)newFinal;
long double newLong = newFinal - intPart;
if (newLong == 0) {
NSLog(#"Integer");
//Return only the final ints?
}
}
}
Just cast it to an int and subtract it from itself?
long double d;
//assign a value to d
int i = (int)d;
if((double)(d - i) == 0) {
//d has no fractional part
}
As a note... because of the way floating point math works in programming, this == check isn't necessarily the best thing to do. Better would be to decide on a certain level of tolerance, and check whether d was within that tolerance.
For example:
if(fabs((double)(d - i)) < 0.000001) {
//d's fractional part is close enough to 0 for your purposes
}
You can also use long long int and long double to accomplish the same thing. Just be sure you're using the right absolute value function for whatever type you're using:
fabsf(float)
fabs(double)
fabsl(long double)
EDIT... Based on clarification of the actual problem... it seems you're just trying to figure out how to return a collection from a method.
-(NSMutableArray*)yourMethodName {
NSMutableArray *retnArr = [NSMutableArray array];
for(/*some loop logic*/) {
// logic to determine if the number is an int
if(/*number is an int*/) {
[retnArr addObject:[NSNumber numberWithInt:/*current number*/]];
}
}
return retnArr;
}
Stick your logic into this method. Once you've found a number you want to return, stick it into the array using the [retnArr addObject:[NSNumber numberWithInt:]]; method I put up there.
Once you've returned the array, access the numbers like this:
[[arrReturnedFromMethod objectAtIndex:someIndex] intValue];
Optionally, you might want to throw them into the NSNumber object as different types.
You can also use:
[NSNumber numberWithDouble:]
[NSNumber numberWithLongLong:]
And there are matching getters (doubleValue,longLongValue) to extract the number. There are lots of other methods for NSNumber, but these seem the most likely you'd want to be using.
I have this equation
double x = ((newCount/allCount)/.8)*5.0;
newCount is a double with value 0
allCount is a double with value 0
the result of x is -nan(0x8000000000000)
why this happens and how to check this value in objective c to assign default value for it
You are diving by zero. You can check for it using:
isnan(x)
The problem is that the denominator (allCount) is 0; dividing by zero is not allowed and the answer is not a number. The simplest thing you could do is to test for that before doing the division:
if (allCount != 0) {
x = ((newCount/allCount)/.8)*5.0
} else {
x = defaultValue;
}
There are more complicated ways using C's floating point environment and testing for the FE_DIVBYZERO exception, but while that's standard it's rarely used and therefore potentially more difficult for a later reader of the code to comprehend.
allCount is a 0, thus you just divided by 0 (which is impossible if you didn't know..) So before you assign x, just make sure that allCount is not 0 first.
if (allCount != 0)
double x = ((newCount/allCount)/.8)*5.0;
I have two NSDecimalNumbers and I need to apply one to the power of the other, originally this code was using doubles and I could compute this with the pow() function like this:
double result = pow(value1, value2);
The problem I have is I am converting the code to use NSDecimalNumbers and although they include the method toThePowerOf, it only accepts int values. At the moment the only solution I have to this problem is to convert the NSDecimalNumbers Temporarily but this results in a loss of precision.
double value1 = [decimal1 doubleValue];
double value2 = [decimal2 doubleValue];
double result = pow(value1, value2);
NSDecimalNumber *decimalResult = [[NSDecimalNumber alloc] initWithDouble:result];
Is there a way I can do this computation with NSDecimalNumbers and not lose the precision?
I need this to work with non integer values for example:
value1 = 1.06
value2 = 0.0277777777
As Joe points out, if you want to do this for positive integer powers, you can use NSDecimalPower() on an NSDecimal struct derived from your NSDecimalNumber (I personally prefer working with the structs, for performance reasons).
For the more general case of working with negative integers and fractional values, I have some code that I've modified from Dave DeLong's DDMathParser library. He has since removed the NSDecimal portion of this library, but you can find the last commit for this support. I extended Dave's exponential support into the following function:
extern NSDecimal DDDecimalPower(NSDecimal d, NSDecimal power) {
NSDecimal r = DDDecimalOne();
NSDecimal zero = DDDecimalZero();
NSComparisonResult compareToZero = NSDecimalCompare(&zero, &power);
if (compareToZero == NSOrderedSame) {
return r;
}
if (DDDecimalIsInteger(power))
{
if (compareToZero == NSOrderedAscending)
{
// we can only use the NSDecimal function for positive integers
NSUInteger p = DDUIntegerFromDecimal(power);
NSDecimalPower(&r, &d, p, NSRoundBankers);
}
else
{
// For negative integers, we can take the inverse of the positive root
NSUInteger p = DDUIntegerFromDecimal(power);
p = -p;
NSDecimalPower(&r, &d, p, NSRoundBankers);
r = DDDecimalInverse(r);
}
} else {
// Check whether this is the inverse of an integer
NSDecimal inversePower = DDDecimalInverse(power);
NSDecimalRound(&inversePower, &inversePower, 34, NSRoundBankers); // Round to 34 digits to deal with cases like 1/3
if (DDDecimalIsInteger(inversePower))
{
r = DDDecimalNthRoot(d, inversePower);
}
else
{
double base = DDDoubleFromDecimal(d);
double p = DDDoubleFromDecimal(power);
double result = pow(base, p);
r = DDDecimalFromDouble(result);
}
}
return r;
}
This runs exact calculations on positive integer powers, negative integer powers, and fractional powers that map directly to roots. It still falls back on floating point calculations for fractional powers that don't cleanly fall into one of those bins, though.
Unfortunately, this requires a few of his other supporting functions to work. Therefore, I've uploaded my enhanced versions of his _DDDecimalFunctions.h and _DDDecimalFunctions.m that provide this functionality. They also include NSDecimal trigonometry, logarithm, and a few other functions. There are currently some issues with convergence on the tangent implementation, which is why I haven't finished a public post about this.
I came across the same problem recently and developed my own function to do exactly this. The function has will calculate any base to any power as long as it yields a real answer if it determines a real answer cannot be calculated it returns NSDecimalnumber.notANumber
I have posted my solution as an answer to the same question that I posted so here is the link.
How can you test whether the square root of a number will be rational or not?
Is this even possible?
I need this because I need to work out whether to display a number as a surd or not in a maths app I'm developing at the moment.
For integer inputs, only the square roots of the square numbers are rationals. So your problem boils down to find if your number is a square number. Compare the question: What's a good algorithm to determine if an input is a perfect square?.
If you have rational numbers as inputs (that is, a number given as the ratio between two integer numbers), check that both divisor and dividend are perfect squares.
For floating-point values, there is probably no solution because you can't check if a number is rational with the truncated decimal representation.
From wikipedia: The square root of x is rational if and only if x is a rational number that can be represented as a ratio of two perfect squares.
So you need to find a rational approxmiation for your input number. So far the only algorithm I've nailed down that does this task is written in Saturn Assembler for the HP48 series of calculators.
After reading comments and the answers to another question I have since asked, I realised that the problem came from a floating point inaccuracy which meant that some values (eg 0.01) would fail the logical test at the end of the program. I have amended it to use NSDecimalNumber variables instead.
double num, originalnum, multiplier;
int a;
NSLog(#"Enter a number");
scanf("%lf", &num);
//keep a copy of the original number
originalnum = num;
//increases the number until it is an integer, and stores the amount of times it does it in a
for (a=1; fmod(num, 1) != 0 ; a++) {
num *= 10;
}
a--;
//when square-rooted the decimal points have to be added back in
multiplier = pow(10, (a/2));
if (fmod(originalnum, 1) != 0) {
multiplier = 10;
}
NSDecimalNumber *temp = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:sqrt(num)/multiplier] decimalValue]];
NSDecimalNumber *result = [temp decimalNumberByMultiplyingBy:temp];
NSDecimalNumber *originum = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:originalnum] decimalValue]];
if ((fmod(sqrt(num), 1) == 0) && ([result isEqualToNumber:originum])) {
NSLog(#"The square root of %g is %#", originalnum, temp);
}
else {
NSLog(#"The square root of this number is irrational");
}
If you're dealing with integers, note that a positive integer has a rational square root if and only if it has an integer square root, that is, if it is a perfect square. For information on testing for that, please see this amazing StackOverflow question.
On https://math.stackexchange.com/ there is the question What rational numbers have rational square roots? that yielded an answer from Jakube that states that for "...rational numbers, an answer is to determine if the numerator and denominator are integers raised to the power of 2."
Good ways to work out whether natural numbers are perfect squares depends on the natural numbers the function supports (and the computer programming language being used) and the memory available etc. Here are a set of useful links:
https://math.stackexchange.com/questions/3431150/is-there-a-way-to-check-if-an-integer-is-a-square
https://codereview.stackexchange.com/questions/204974/fastest-way-to-determine-if-a-number-is-perfect-square
Fastest way to determine if an integer's square root is an integer
Check if BigInteger is not a perfect square
I developed and tested a solution in Java that works well enough for me with a set of natural numbers. The gist of this is given below. This code depends on BigMath and is implemented in agdt-java-math albeit in a couple of different classes:
/**
* #param x The number to return the square root of (if the result is
* rational).
* #return The square root of x if that square root is rational and
* {#code null} otherwise.
*/
public static BigRational getSqrtRational(BigRational x) {
BigInteger[] numden = getNumeratorAndDenominator(x);
BigInteger nums = getPerfectSquareRoot(numden[0]);
if (nums != null) {
BigInteger dens = getPerfectSquareRoot(numden[1]);
if (dens != null) {
return BigRational.valueOf(nums).divide(BigRational.valueOf(dens));
}
}
return null;
}
/**
* #param x The value for which the numerator and denominator are returned.
* #return The numerator and denominator of {#code x}
*/
public static BigInteger[] getNumeratorAndDenominator(BigRational x) {
BigInteger[] r = new BigInteger[2];
r[0] = x.getNumeratorBigInteger();
r[1] = x.getDenominatorBigInteger();
if (Math_BigInteger.isDivisibleBy(r[0], r[1])) {
r[0] = r[0].divide(r[1]);
r[1] = BigInteger.ONE;
}
return r;
}
/**
* #param x The number to return the square root of if that is an integer.
* #return The square root of {#code x} if it is an integer and {#code null}
* otherwise.
*/
public static BigInteger getPerfectSquareRoot(BigInteger x) {
if (x.compareTo(BigInteger.ZERO) != 1) {
return null;
}
BigInteger xs = x.sqrt();
if (x.compareTo(xs.multiply(xs)) == 0) {
return xs;
}
return null;
}
Also as square of any rational is rational, no rational is the square root of an irrational. This is clear to me having read Yves answer to: Prove that the square root of any irrational number is irrational. So, dealing with the case of rational numbers is sufficient to answer this question for all real numbers.