double datatype+iphone - iphone

i have a one application i know The range of a double is **1.7E +/- 308 (15 digits).**but in my application i have to devide text box 's value to 100.0 my code is
double value=[strPrice doubleValue]/100.0;
NSString *stramoount=[#"" stringByAppendingFormat:#"%0.2f",value ];
when i devide 34901234566781212 by 100 it give me 349012345667812.12 but when i type
349012345667812124 and devide by 100 it give me by 100 it give me 3490123456678121.00 which is wrong whether i change datatype or how can i change my code

The number 349012345667812124 has 18 decimal digits. the double format only provides slightly less than 16 decimal digits of precision (the actual number is not an integer because the format's binary digits do not correspont directly to decimal ones). Thus it is completely expected that the last 2 or 3 digits cannot be represented accurately, and it already happens when the literal "349012345667812124" is parsed to the double format, before any calculations happen.
The fact that you get the expected result with the number 34901234566781212 means nothing; it just happens to be close enough to the nearest value the double format can represent.
To avoid this problem, use the NSDecimal or NSDecimalNumber types.

Use
NSDecimalNumber * dec=[[NSDecimalNumber decimalNumberWithString:value.text locale: [NSLocale currentLocale]] decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:#"100" locale:[NSLocale currentLocale]]];
NSLog(#"%#",dec);
instead of Double

Related

Add leading and trailing zeroes to a string/label in swift

In swift I know how to set the number of digits after the decimal point when converting a double to a string:
String(format: "%0.2f", someDouble)
Similarly I know how to set the number of digits before the decimal point:
String(format: "%02d", someDouble)
But how can I do both?
I want the string to always have a 00.00 format.
Thanks
You simply combine the two:
String(format: "%05.2f", someDouble)
The 0 means fill with leading zeros as needed.
The 5 means you want the final output to be at least 5 characters, include the decimal point.
The .2 means you want two decimal places.
If this is a number you are showing to a user then you should probably use NumberFormatter so the decimal is properly formatted for the user's locale.

Double being displayed with unnecessary zeros after decimal

In my calculator app, I am trying to display a "double" value in a UILabel. However, the value always has more zeros than it needs. For example, 64 is displayed as 64.000000, 4.23 is displayed as 4.230000, etc.
How can I make it display only as many decimal places as fits?
vector<Token> postfix; // create empty postfix vector
infixToPostfix(infix, postfix); // call inToPost to fill up postfix vector from infix vector
answer = postFixEvaluate(postfix); // evaluate expression
expString.clear();
expNSString = [NSString stringWithFormat:#"%f", answer]; // convert "answer" to NSString
displayScreen.text = expNSString; // display answer in UIlabel "displayScreen"
As mentioned in the [NSString stringWithFormat:] class reference:
Parameters
format A format string. See “Formatting String Objects” for
examples of how to use this method, and “String Format Specifiers” for
a list of format specifiers. This value must not be nil.
and following the first link, one of the first examples is:
NSString *string1 = [NSString stringWithFormat:#"A string: %#, a float: %1.2f",
#"string", 31415.9265]; // ^
// string1 is "A string: string, a float: 31415.93"
You need to learn to think for yourself. Read the documentation!
This question is a little old, but did you try %g? This will produce scientific notation in some cases:
64-bit floating-point number (double), printed in the style of %e if the exponent is less than –4 or greater than or equal to the precision, in the style of %f otherwise.
But, as it says, you can control this to some extent using the precision field: if your numbers are large, you will need to increase the precision to avoid scientific notation. If your numbers are small, then I think there is nothing you can do about it when using %g.
I get this output:
64.0 -> "64"
64.1 -> "64.1"
64.15555 -> "64.1556" // default precision is 6

doubleValue does not convert the object to a double value correctly at all times

I have an NSArray in which I would like to store double values. I defined it as follow
NSMutableArray *setOfDoubles;
I add the elements as follow
NSNumber *num;
num = [NSNumber numberWithDouble:someDouble];
[setOfDoubles addObject:num];
And I read the element as follow
num = [setOfDoubles lastObject];
[setOfDoubles removeLastObject];
doubleValueToUse = [num doubleValue];
My problem is sometimes (Not always), for example when num (as an object) is 5.1, doubleValueToUse (as a double value) is 5.099999999999996. The way I figured num (as an object) is 5.1 is that I debug and when I am hovering the mouse on top of num on the line num = [setOfDoubles lastObject]; it shows 5.1 but after doubleValue conversion it becomes the number I mentioned. Does anybody know why is this happening?
Not every number can be accurately represented using a float variable. For example, you can't precisely represent, say, 1/3 using a finite number of digits in our common decimal (base-10) system, but in ternary (base-3), it would be just 0.1. Similarly, the numbers you can write with a finite number of digits in decimal, may not necessarily have the finite number of digits in their binary representation, hence the error.
A few links on the topic if you are interested:
http://floating-point-gui.de/basic/
http://www.mathworks.com/support/tech-notes/1100/1108.html
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
This is normal for float values.
If you want to save initial (same) representation of float numbers in all places of your code, you can save them, for example, in NSString. When you will need float number you will just write [NSString floatValue];. But it is not effective if you have large amount of float values.

53 * .01 = .531250

I'm converting a string date/time to a numerical time value. In my case I'm only using it to determine if something is newer/older than something else, so this little decimal problem is not a real problem. It doesn't need to be seconds precise. But still it has me scratching my head and I'd like to know why..
My date comes in a string format of #"2010-09-08T17:33:53+0000". So I wrote this little method to return a time value. Before anyone jumps on how many seconds there are in months with 28 days or 31 days I don't care. In my math it's fine to assume all months have 31 days and years have 31*12 days because I don't need the difference between two points in time, only to know if one point in time is later than another.
-(float) uniqueTimeFromCreatedTime: (NSString *)created_time {
float time;
if ([created_time length]>19) {
time = ([[created_time substringWithRange:NSMakeRange(2, 2)]floatValue]-10) * 535680; // max for 12 months is 535680.. uh oh y2100 bug!
time=time + [[created_time substringWithRange:NSMakeRange(5, 2)]floatValue] * 44640; // to make it easy and since it doesn't matter we assume 31 days
time=time + [[created_time substringWithRange:NSMakeRange(8, 2)]floatValue] * 1440;
time=time + [[created_time substringWithRange:NSMakeRange(11, 2)]floatValue] * 60;
time=time + [[created_time substringWithRange:NSMakeRange(14, 2)]floatValue];
time = time + [[created_time substringWithRange:NSMakeRange(17, 2)]floatValue] * .01;
return time;
}
else {
//NSLog(#"error - time string not long enough");
return 0.0;
}
}
When passed that very string listed above the result should be 414333.53, but instead it is returning 414333.531250.
When I toss an NSLog in between each time= to track where it goes off I get this result:
time 0.000000
time 401760.000000
time 413280.000000
time 414300.000000
time 414333.000000
floatvalue 53.000000
time 414333.531250
Created Time: 2010-09-08T17:33:53+0000 414333.531250
So that last floatValue returned 53.0000 but when I multiply it by .01 it turns into .53125. I also tried intValue and it did the same thing.
Welcome to floating point rounding errors. If you want accuracy two a fixed number of decimal points, multiply by 100 (for 2 decimal points) then round() it and divide it by 100. So long as the number isn't obscenely large (occupies more than I think 57 bits) then you should be fine and not have any rounding problems on the division back down.
EDIT: My note about 57 bits should be noted I was assuming double, floats have far less precision. Do as another reader suggests and switch to double if possible.
IEEE floats only have 24 effective bits of mantissa (roughly between 7 and 8 decimal digits). 0.00125 is the 24th bit rounding error between 414333.53 and the nearest float representation, since the exact number 414333.53 requires 8 decimal digits. 53 * 0.01 by itself will come out a lot more accurately before you add it to the bigger number and lose precision in the resulting sum. (This shows why addition/subtraction between numbers of very different sizes in not a good thing from a numerical point of view when calculating with floating point arithmetic.)
This is from a classic floating point error resulting from how the number is represented in bits. First, use double instead of float, as it is quite fast to use on modern machines. When the result really really matters, use the decimal type, which is 20x slower but 100% accurate.
You can create NSDate instances form those NSString dates using the +dateWithString: method. It takes strings formatted as YYYY-MM-DD HH:MM:SS ±HHMM, which is what you're dealing with. Once you have two NSDates, you can use the -compare: method to see which one is later in time.
You could try multiplying all your constants by by 100 so you don't have to divide. The division is what's causing the problem because dividing by 100 produces a repeating pattern in binary.

Rounding Off Decimal Value to Pevious and Next Hundreds

I am working in C#. I have decimal variable startFilter that contains value say 66.76. Now I want this decimal value to appear in the seach filter $0 to $100. But what I also want is, that the search filter starts from the first decimal value that comes in startFilter variable. So for instance in this case the search filter will start from $0 to $100 because the value in startFilter variable is 66.76, but in another case it can be $100 to $200 if the first value that comes in searchFilter is say $105.
Having said that, how should I round off the value in seachFilter to previous hundreds and the next hundreds. Like if the value is 66.76 it rounds off to 0 as floor and 100 as ceiling, so on and so forth.
Any idea how to do that in C#?
double value = ...
int rounded = ((int) Math.Round(value / 100.0)) * 100;
divide your original number by 100. get floor and celing values. Multiply each of them by 100.