stringWitFormat using a zero padded float - ios

double knots = currentLocation.speed*1.943844492;
NSString *speed = [NSString stringWithFormat:#"%03.1f", knots];
This results a normal single decimal float without leading zero's.
The purpose is to get max 3 leading digits and single decimal.

The 3 is the total length including the decimal point and the decimal digit. Change the 3 to 5 and you should get what you want:
NSString *speed = [NSString stringWithFormat:#"%05.1f", knots];

Related

How to convert float value into same NSString

How I can convert float value in NSString but value should be same as float. If float f = 34.000 then NSString also have 34.000.
I want that my float value should not be changed whatever it have value of 2 decimal then string should be 2 decimal if it have 3 decimal also then string should be 3 decimal.
I used many concept but nothing help
Thanks
You can use stringWithFormat:
[NSString stringWithFormat:#"%f", myFloat];
what you must understand is that your float is not equal to 34.000 or 34.0... it is equal to {0x00 0x00 0x08 0x42} which can be represented in decimal as 34, 34.0, 34.0000000000 .... how you want to represent the value is up to you, and that what %f is for : %.2f will display only 2 decimal after the .
You want:
float f = 34.0f;
NSString *str = [NSString stringWithFormat:#"%.3f", f];
(the .3 will give you 3 decimal places)
try this
let floatValye: Float = 0.1111
let stringValue : String = String(format: "%.3f",floatValye)

Converting NSString to float, the result is wrong

Here is the code:
NSString *val = #"51785239";
unsigned long long valFromFloat = 0L;
unsigned long long valFromLL = 0L;
valFromFloat = [val floatValue];
valFromLL = [val integerValue];
I was testing this code, the result is: valFromFloat = 51785240.0, valFromLL = 51785239.
Why valFromFloat is 51785240.0? I thought it should be 51785239.0.
Please, someone can explain it?
You seem to be confused over floating point vs. integer types, and misunderstand floating point precision.
Why valFromFloat is 51785240.0?
It isn't. valFromFloat is a variable of integer type, specifically unsigned long long, so its value certainly has no decimal fractional part.
The statement:
valFromFloat = [val floatValue];
first calls a method to parse (interpret) the string value val as a float value, which is the low precision floating-point type. That float value is then converted to an unsigned long long value and stored into valFromFloat.
Try:
float asFloat = [val floatValue];
double asDouble = [val doubleValue];
int asInt = [val intValue];
NSLog(#"float: %f | double: %f | int: %d", asFloat, asDouble, asInt);
and see what you get. Then lookup floating-point precision and the difference between binary floating-point, such as the types float and double, and decimal floating-point types, such as NSDecimal and NSDecimalNumber.
HTH
The float
The screenshot from MacTypes.h.
As we can see the float 【Float32】 is 32 bit IEEE float: 1 sign bit, 8 exponent bits, 23 fraction bits.
And we can get the bellow images from https://en.wikipedia.org/wiki/Single-precision_floating-point_format
Then we can convert the string to float as bellow:
51785239(10)=11000101100010111000010111(2)
Also IEEE 754 binary32 format requires that you represent real values in format, so that 11000101100010111000010111 is shifted to the right by 25 digits to become
From which we deduce:
The exponent is 25 (and in the biased form it is therefore 152 = 1001 1000)
The fraction is 1000101100010111000011000 (looking to the right 25 bits of the binary point whitch is rounding to 1000101100010111000011000)
thus:
Change
valFromFloat = [val floatValue];
to
valFromFloat = [val doubleValue];
(and think about what a float is).
NSString *string_val =#"51785239.65";
float float_val=[string_val floatValue];

adding total sum with floating points

In xcode I am utilizing 4 utitextfields for the following chart that the user will enter a whole number, chart is the following:
Total | Win | Place | Show
34 | 4 | 5 | 3
My algorithm for this chart is the following:
-For total win * 1
-For total place * .5
-For total Show * .25
-Add the three totals into a new Float value (identified as,
float totalTrackAllTogether)
-Divide totalTrackAllTogether by the total column (identified as,
int trackTotalColum)
-Display the sum on onOffLabel.text
Here is the code portion that does not seem to work and crashes
-(void)trackRecordMath
{
int trackWinColum = [trackWin.text intValue];
int trackPlaceColum = [trackPlace.text floatValue];
int trackShowColum = [trackShow.text floatValue];
int trackTotalColum= [trackTotal.text intValue];
int trackWinTotal = trackWinColum * 1;
NSLog(#"%d", trackWinTotal);
int trackPlaceTotal = trackPlaceColum *.5;
NSLog(#"%d", trackPlaceTotal);
int trackShowTotal= trackShowColum *.25;
NSLog(#"%d", trackShowTotal);
float totalOfTrackColums = trackWinTotal + trackPlaceTotal + trackShowTotal;
float totalTrackAllTogether= (float) totalOfTrackColums / trackTotalColum;
onOffLabel.text = [[NSString alloc] initWithFormat:#"%f", totalTrackAllTogether];
}
I seem to be held up when trying to multiply floating points with whole numbers, and displaying it through onOffLabel.text. Thank you for the help!
These is basic stuff which works the same in C, C++ and Objective-C. If you do a floating-point calculation and store the result in an int, everything after the decimal point is dropped.
Furthermore, by using float instead of double you get massive rounding errors without any benefit. Instead of
int trackPlaceColum = [trackPlace.text floatValue];
write own of these:
NSInteger trackPlaceColumn = [trackPlace.text integerValue];
double trackPlaceColumn = [trackPlace.text doubleValue];
BTW. It's a column, not a colum. And you will get a crash if you divide by zero. So check whether trackTotalColumn is zero or not in your code.

how to save a float to nsnumber with just two decimals

I'm trying to save a float to an nsnumber but i just want to save it with two decimal places. I know I can do it by converting to an NSString first using this code
NSString* formattedNumber = [NSString stringWithFormat:#"%.02f", myFloat];
but seems clumsy. All I want to do is convert
float numb = 23.25454 into NSNumber 23.25
Use this
float numb = 23.25454;
NSNumber *num = #((int)(numb*100)/100.0);
Just round it using any of these functions
float rounded = round(val * 100) / 100;
float rounded_down = floorf(val * 100) / 100;
float nearest = floorf(val * 100 + 0.5) / 100;
float rounded_up = ceilf(val * 100) / 100;
If you're looking for an object oriented approach, try using NSDecimalNumber which is a subclass of NSNumber. Init the NSDecimalNumber with your float value and then call decimalNumberByRoundingAccordingToBehavior:. This gives you a few options of how the truncation or rounding occurs with NSDecimalNumberBehaviors, where you can set the scale (number of digits following the decimal) and an NSRoundingMode. Check the docs for more info.
It is impossible to do this with float, double, or either of those wrapped as an NSNumber. You need to understand how floating point works.
All these use binary numbers, you wish to represent a number with exactly two decimal places. A binary fraction is made up from a sum of 1/2, 1/4, 1/8, 1/16... while a decimal fraction is a sum of 1/10, 1/100, 1/1000... Not all values which can be represented as a sum of values in one of this series can be represented as a sum in the other. This is a similar issue to representing 1/3 in decimal, it is 3/10 + 3/100 + 3/1000 + .....
Try writing, for example, 0.17 = 17/100 = 1/10 + 7/100 as a sum of 1/2, 1/4 etc. Well it's 1/8 + 9/200 = 1/8 + 1/32 + 11/8000 (I'm just doing this on the fly, excuse any errors!) = you figure it out!
To address this there is the NSDecimalNumber class, which is a subclass of NSNumber and represents numbers in base-10. The class provides the basic operations to do base-10 arithmetic. You can't mix arithmetic easily between base-10 and base-2 numbers, you cannot even create an NSDecimalNumber directly from a float or double - you format the later as an NSString (i.e. convert them to a base-10 representation) - and extracting a double value with the doubleValue method is described as:
The approximate value of the receiver as a double.
Note the approximate.
So a long answer to get to a question: do you really want to store a float or double value to exactly two decimal places?
You can use the round, floor & ceil families to do it approximately, but be prepared for results that are "wrong". E.g. try:
float a = 371371.28127;
float b = roundf(a * 100.0) / 100.0;
NSLog(#"a: %f | b: %f", a, b);
HTH
NSDecimalNumber with NSDecimalNumberHandler is the best way to get accurate precisions if you want as Object. Below is the sample code.
-(NSDecimalNumber *)getRoundedNumberAfterPointDigitsCount:(int)digitsCount withDouble:(double)doubleValue{
NSDecimalNumber *decimalNumber = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%f",doubleValue]];
NSDecimalNumberHandler *decimalHandler = [[NSDecimalNumberHandler alloc] initWithRoundingMode:NSRoundPlain scale:digitsCount raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
decimalNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:decimalHandler];
return decimalNumber;
}
There is more of Rounding option available with NSRoundingMode.
float numb = 23.25454;
float myFloat = roundf(100 * numb) / 100.0;
NSNumber *number = [NSNumber numberWithFloat:myFloat];

Formatting an integer value

Im obtaining an int value from UITextField [self.dbRef.text intValue];
I want to then format that value so I can add a decimal place that precceds the number ie. If [self.dbRef.text intValue]; returns 4 i need that value to be 0.04
So far I have tried various ways including
float Y = ([self.dbRef.text intValue]/100);
slice.value = Y;
NSLog(#"float Y value = %f",Y);
returns zero
NSString* formatedTotalApplianceString = [NSString stringWithFormat:#"0.%#", self.dbRef.text];
NSLog(#"formated string = %#",formatedTotalApplianceString);
int totalAppliances = [formatedTotalApplianceString intValue];
NSLog(#"Resulting int value = %d",[formatedTotalApplianceString intValue]);
slice.value = totalAppliances;
NSLog(#"total appliances int value = %d",totalAppliances);
returns zero
You're doing an integer division, so the 0 value is correct in that context as integers cannot represent fractions (unless you're doing fixed point arithmetics, but that's a different can of worms). You need to do a floating point division, for example:
float Y = ([self.dbRef.text floatValue]/100.0f);
Either the [self.dbRef.text floatValue] or the 100.0f will turn this into a float division, because if the other side would be an int it would automatically get casted to a float. But the "best" way is to have both values of the same type.
Change
float Y = [self.dbRef.text intValue]/100;
to
float Y = ((float)[self.dbRef.text intValue])/100;
in your first variant.
Dividing int by int returns you int result even if then you assign it to float. 4/100 = 0 in such case.
The problem with [self.dbRef.text intValue]/100 is that it's an integer division. It drops the fraction. One way to work around it is to divide by 100.0:
[self.dbRef.text intValue]/100.0
However, this is not the most efficient way of doing it if all you need is adding a zero in front of a fraction: you could avoid float altogether by padding your printed int to two positions with leading zeros:
// If text is 4, the code below prints 0.04
NSLog(#"0.%02d", [self.dbRef.text intValue]);
The first code returns zero because you are performing an integer division, which produces an integer result. You should cast the value to a float.
The second code also returns zero because you're asking for the intValue of a floating point value. So the decimal part will be discarded.
NSString has also a floatValue method, you should use it to get a floating value. Once divided by 100 you will still have a floating point value (in a division if the quotient or the dividend is a float and the other an integer, the integer gets promoted to float):
float Y = ([self.dbRef.text floatValue]/100);
slice.value = Y;

Resources