Reputation: 820
I ran into a pretty weird issue today. I have this static method (part of a CommonUtilities source file that I've been just created that gathers all the small common methods I'd like to access anywhere in my code, like I usually do btw...)
I just want to convert a number into its scientific value using the international system notation (k, M, G, etc.)
Here is the code:
+ (NSString*)scientificFormatedStringForValue:(NSNumber*)value andUnits:(NSString*)_units
{
NSMutableString* retStr = [NSMutableString string];
long long longValue = [value longLongValue];
if (longValue > 1000000000)
{
[retStr appendFormat:@"%d Md%@", longValue / 1000000000, _units];
}
else if (longValue > 1000000)
{
[retStr appendFormat:@"%d M%@", longValue / 1000000, _units];
}
else if (longValue > 1000)
{
[retStr appendFormat:@"%d k%@", longValue / 1000, _units];
}
else
{
[retStr appendFormat:@"%d %@", longValue, _units];
}
return retStr;
}
This is pretty easy right?
Ok, here's the deal: the _units
is not converted properly.
In my example, I use this:
[CommonUtilities scientificFormatedStringForValue:[NSNumber numberWithLongLong:longValue] andUnits:@"€"];
I get (null)
as _units
for the formatted string. If I print the value of _units
, it's a dot. So, to try to debug this, I just replaced:
[retStr appendFormat:@"%d M%@", longValue / 1000000, _units];
with
[retStr appendFormat:@"%d M%@", longValue / 1000000, @"€"];
Still doesn't work. It tried passing a single character (thinking the maybe the € must be converted to some UTF8 stuff or whatever. So I changed the calling method to :
[CommonUtilities scientificFormatedStringForValue:[NSNumber numberWithLongLong:longValue] andUnits:@"e"];
Still crappy stuff. I even changed @"€" to [NSString stringWithString:@"€"], but still the same output! I can't figure out what's wrong here, I'm stuck.
I thought of a problem in the encoding of the source file, so I deleted it and recreated it, but still the same issue....
If any one has even the tiniest clue, that would be most helpful. Thank you guys...
Upvotes: 4
Views: 134
Reputation: 57169
The problem is you are attempting to write an int
(32 bits) but you are passing a long long
(64 bits) and it is reading the first 4 bytes of your longValue
for the value
and the last 4 bytes for the _units
. It just so happens that the value in low bytes of your long long
is nil
and did not cause a crash. You need to use %lld
instead of %d
to print the long value correctly.
longValue NSString*
/---------------\ /---------\
| 8 bytes | | 4 bytes |
\---------------/ \---------/
^^^^^^^^ ^^^^^^^^ ^^^^^^^^^
%d %@ This gets ignored.
(reads 4) (reads this 4 bytes which happen to be nil)
Upvotes: 3