taking absolute value of CGFloat - iphone

How can I do that? I tried the abs() but it only works for int's. Is there a built in way to do so?
CGFloat flo = -123;
abs(flo)
this returns 0

Use fabs()
CGFloat f = -123.4f;
CGFloat g = fabs(f);
CGFloat is defined as a double on 64-bit machines, and float on 32-bit machines. If you are targeting both 64 and 32 bit than this answer gets more complicated, but is still correct.
You want to use fabs() because it works on double datatypes which are larger than float. On 32-bit, assigning the return value of fabs() (which is a double) into a CGFloat (which is a float) is ok ONLY if you are taking the absolute value of a CGFloat or float. You would potentially overflow a 32-bit CGFloat if you try to store the absolute value of a large double number. In short, 64-bit is fine, and on 32-bit don't mix and match double and CGFloat and you'll be fine.
The ABS() macro apparently can have side-effects on some compilers.

For 64/32 bit system
#if CGFLOAT_IS_DOUBLE
CGFloat g = fabs(flo);
#else
CGFloat g = fabsf(flo);
#endif

I normally just use the ABS macro, as far as I can tell, it works regardless of which system you're on or which primitive you're using.
CGFloat x = -1.1;
double y = -2.1;
NSInteger z = -5;
x = ABS(x);
y = ABS(y);
z = ABS(z);

Small addition:
CGFloat g = fabs(f);
This will result in a casting warning, because fabs() returns a double value.
To get a float value back, you need to use fabsf().
CGFloat g = fabsf(f);

fabs is depreciated. The signature of abs is now generic with this signature
/// Returns the absolute value of the given number.
///
/// The absolute value of `x` must be representable in the same type. In
/// particular, the absolute value of a signed, fixed-width integer type's
/// minimum cannot be represented.
///
/// let x = Int8.min
/// // x == -128
/// let y = abs(x)
/// // Overflow error
///
/// - Parameter x: A signed number.
/// - Returns: The absolute value of `x`.
#inlinable public func abs<T>(_ x: T) -> T where T : Comparable, T : SignedNumeric

Related

Failed to multiply double in dart

I got an error when trying to multiply a number with a floating point in dart. Does anyone know why this happens?
void main() {
double x = 37.8;
int y = 100;
var z = x * y;
print(z);
// 3779.9999999999995
}
In other languages ​​(C#/C++) I would have the result: 3780.0
This is completely expected because 37.8 (or rather, the 0.8 part) cannot be precisely encoded as a binary fraction in the IEEE754 standard so instead you get a close approximation that will include an error term in the LSBs of the fraction.
If you need numbers that are lossless (e.g. if you are handling monetary calculations) then check out the decimal package.
A simpler hack if your floating point number has sufficient bits allocated to the fraction to keep the erroroneous bits out of the way is to round off the number after your calculation to the number of decimal places that you care about.
You can use toStringAsFixed to control fraction digits.
void main() {
double x = 37.8;
int y = 100;
var z = x * y;
print(z.toStringAsFixed(1));
// 3780.0
}

Conversion from Float to CGFloat in Swift

I was converting Float => CGFloat and it gave me following result. Why It comes as "0.349999994039536" after conversion but works fine with Double => CGFloat?
let float: Float = 0.35
let cgFloat = CGFloat(float)
print(cgFloat)
// 0.349999994039536
let double: Double = 0.35
let cgFloat = CGFloat(double)
print(cgFloat)
// 0.35
Both converting “.35” to float and converting “.35” to double produce a value that differs from .35, because the floating-point formats use a binary base, so the exact mathematical value must be approximated using powers of two (negative powers of two in this case).
Because the float format uses fewer bits, its result is less precise and, in this case, less accurate. The float value is 0.3499999940395355224609375, and the double value is 0.34999999999999997779553950749686919152736663818359375.
I am not completely conversant with Swift, but I suspect the algorithm it is using to convert a CGFloat to decimal (with default options) is something like:
Produce a fixed number of decimal digits, with correct rounding from the actual value of the CGFloat to the number of digits, and then suppress any trailing zeroes. For example, if the exact mathematical value is 0.34999999999999997…, and the formatting uses 15 significant digits, the intermediate result is “0.350000000000000”, and then this is shorted to “0.35”.
The way this operates with float and double is:
When converted to double, .35 becomes 0.34999999999999997779553950749686919152736663818359375. When printed using the above methods, the result is “0.35”.
When converted to float, .35 becomes 0.3499999940395355224609375. When printed using the above method, the result is “0.349999994039536”.
Thus, both the float and double values differ from .35, but the formatting for printing does not use enough digits to show the deviation for the double value, while it does use enough digits to show the deviation for the float value.

Display Float In UILabel

I am having an issue with using a float in a UILabel.
float doubleNum;
floatNum = 10 / 20;
cashLabel.text = [[NSString alloc] initWithFormat:#"%f", floatNum];
If I use "floatNum = 10 / 10;" it correctly returns "1.000000000", however, if I put in "floatNum = 10 / 20" it returns "0.0000000". I have tried about everything I know and it does not work. I know it's a dumb mistake, but I can't figure it out.
Happy Holidays. :)
You need to cast one of the integer's to a float.
Try replacing the divisional line with:
float floatNum = (float) 10 / 20;
and you should get the correct answer.
Or if possible just use floats in your division:
float floatNum = 10.0f / 20.0f;
should also work
The issue here is that you are assigning floatNum the result of dividing one INTEGER by another. The result of 10 / 20 is indeed 0 and as a float, it appears as 0.0000000. In order to obtain a proper result, you need to either use a cast type to turn it into a float or add a .0 to one of the numbers. In division, if one of the numbers is a float (which is easily done by just adding a .0 to one of them), the result will be a float as well.
Normally, C performs "integer division" (basically, division without the remainder -- 10/3 is 3R1, so it yields 3).
When you type floatNum = 10/20, it does 10/20 = 0 (remainder 10).
To fix this, you have to tell the program that you're giving it floating point numbers. Try using:
floatNum = 10.0 / 20,
floatNum = 10 / 20.0, or
floatNum = float (10 / 20).
All of those should work.
try floatNum = 10.0f/20.0f (i.e. make sure the calculation is being done with floats rather than ints)
Consider following example to understand how floats work:
float a = 1/120;
float b = 1.0/120;
float c = 1.0/120.0;
float d = 1.0f/120.0f;
NSLog(#"Value of A:%f B:%f C:%f D:%f",a,b,c,d);
Output: Value of A:0.000000 B:0.008333 C:0.008333 D:0.008333
For float variable a : int / int yields integer which you are assigning to float and printing it so 0.0000000
For float variable b: float / int yields float, assigning to float and printing it 0.008333
For float variable c: float / float yields float, so 0.008333
Last one is more precise float. Previous ones are of type double: all floating point values are stored as double data types unless the value is followed by an 'f' to specifically specify a float rather than as a double.
Change your code to:
float floatNum;
floatNum = 10.0f / 20.0f;
cashLabel.text = [[NSString alloc] initWithFormat:#"%f", floatNum];

Objective-C Float Rounding

How might I round a float to the nearest integer in Objective-C:
Example:
float f = 45.698f;
int rounded = _______;
NSLog(#"the rounded float is %i",rounded);
should print "the rounded float is 46"
Use the C standard function family round(). roundf() for float, round() for double, and roundl() for long double. You can then cast the result to the integer type of your choice.
The recommended way is in this answer: https://stackoverflow.com/a/4702539/308315
Original answer:
cast it to an int after adding 0.5.
So
NSLog (#"the rounded float is %i", (int) (f + 0.5));
Edit: the way you asked for:
int rounded = (f + 0.5);
NSLog (#"the rounded float is %i", rounded);
For round float to nearest integer use roundf()
roundf(3.2) // 3
roundf(3.6) // 4
You can also use ceil() function for always get upper value from float.
ceil(3.2) // 4
ceil(3.6) // 4
And for lowest value floor()
floorf(3.2) //3
floorf(3.6) //3
The easiest way to round a float in objective-c is lroundf:
float yourFloat = 3.14;
int roundedFloat = lroundf(yourFloat);
NSLog(#"%d",roundedFloat);
Check the manual page for rint()
If in case you want round float value in integer below is the simple method for rounding the float value in objective C.
int roundedValue = roundf(Your float value);
let's do tried and checkout
//Your Number to Round (can be predefined or whatever you need it to be)
float numberToRound = 1.12345;
float min = ([ [[NSString alloc]initWithFormat:#"%.0f",numberToRound] floatValue]);
float max = min + 1;
float maxdif = max - numberToRound;
if (maxdif > .5) {
numberToRound = min;
}else{
numberToRound = max;
}
//numberToRound will now equal it's closest whole number (in this case, it's 1)

pi in Objective C

I keep getting error in my iPhone programing when I try to use pi. I'm trying
float pNumber = 100*cos(2 * pi * (days/23));
But i get errors that say:
_pi, referenced from
_pi$non_lazy_ptr
I saw somewhere on the internet to use M_PI and it compiles but I don't think it gives me the correct calculation.
When I try:
float pNumber = 100*cos(2 * M_PI * (15746/23));
I get 0
Thanks
The integer division probably needs to be coerced into a floating point one (cast one of the numbers to a double - or use the notation 23.0 to indicate that you want a floating point division).
Try printing out M_PI and see what it says (printf("M_PI = %16.9g\n", M_PI); in C).
Did you include the declaration for cos()? If not, it may be interpreted as a function returning an integer (#include <math.h> perhaps).
Example code (tested in C on Solaris 10 SPARC with GCC 4.3.3):
#include <math.h>
#include <stdio.h>
int main(void)
{
float pNumber = 100*cos(2 * M_PI * (15746/23));
printf("M_PI = %16.9g\n", M_PI);
printf("pNum = %16.9g\n", pNumber);
pNumber = 100*cos(2 * M_PI * (15746/23.0));
printf("pNum = %16.9g\n", pNumber);
return 0;
}
Example output:
M_PI = 3.14159265
pNum = 100
pNum = -77.5711288
C/C++ and hence Objective C/C++ does not promote integers to floats when doing normal division.
So in C/C++ the expression 15746/23 evaluates to 567, not to 567.71207 as you might naively expect.
C will promote integers to floats as necessary if one or other operand is a float, so all you need to do is use 15746.0 or 23.0 in your expression, ie change to
float pNumber = 100*cos(2 * M_PI * (15746/23.0));
The 100 will automatically be promoted because cos returns a float (actually a double, but I will ignorefloat/double percissions issues). The 2 is promoted to a float because M_PI is a float. And the 15746 is promoted to a float because 23.0 is a float.
However, it would not hurt to add the .0 to all the constants, ie:
float pNumber = 100.0*cos(2.0 * M_PI * (15746.0/23.0));
The problem is the integer division in the innermost part of the expression, which truncates the value (omitting the fractional part). One option, as mentioned, is to make every constant a floating point number, either by adding ".0" or "f" after it. Alternatively, you can omit the parentheses from the innermost expression entirely. Since M_PI is a floating point number, and multiplication in C is left-associative (meaning it proceeds from left to right) the first multiplication (2 * M_PI) will be promoted to a float, as will each successive multiply. Since cos() returns a float, pNumber will be assigned a float without having performed any integer division, hence no loss of precision. (Note: It's not usually wise to count on operator associativity or precedence, but in this case I'm just trying to demonstrate that it would in fact work.)
As far as the range of numbers you should expect to see, recall that the cosine (unmodified) ranges from -1 to +1, not 0 to 1, so you would actually see -100 to 100 (in theory). To get the correct range, you'd want to add 1, then multiply by 50.
Incidentally, the compile errors you get in the first case are because pi is not defined. The guidance to use M_PI is correct — for math constants, it's always smarter (and more consistent) to use what the system provides. If you're curious, on Leopard these constants are #defined in Math.h, lines 528-540. You can open the file by using File > Open Quickly... (Cmd-Shift-D) and typing "Math.h", or by double-clicking on M_PI in your code while holding down Command.
Why use a sinusoid in the first place ?
If the goal is to have a fonction ranging from 0 to 100 then 100 to 0 in 23 days, you could use:
// x ranges from 0 to 2
float x = (days % 23)/11.5;
// pNumber is a saw ranging from 0 to 100
float pNumber = 100 * abs(x - 1);
You can also replace the x by a cosine if you really want one, as 2*pi/23 ~= 0.273, you have
float x = 1 + cos((days % 23)*0.273);