Conversion to Binary - long long and NSUInteger - ios

We need to convert the below datatypes to binary:
Long long to Binary
NSUInteger to Binary
Any help on this would be highly appreciated.
The code i have is :
As per the above link, we have
- (NSString *) longlongToBinary:(long long) val {
long long num = val;
NSString *res = [NSString string];
for (long long i=63; i>=0; i--)
{
long long div = 1l<<i;
if ((num&div)==div) res = [res stringByAppendingString:#"1"];
else res = [res stringByAppendingString:#"0"];
}
return res;
}
If the val is 20, then the output i am getting is:
0000000000000000000000000001010000000000000000000000000000010100
and this is wrong when i see it in the online convertors.

long is only 32 bits. Since the method is named longlongToBinary, change all of the long variables to long long. That will give you the 64 bits you are using.
Now that you have changed most variables to long long, change the loop variable i back to an int and change the 1l constant to 1ll.

The literal 1l is still only long. That's why you see the output twice. Change the literal to 1ll

Related

How to convert a NSString to long double?

I am dealing with a long double value that can have huge values.
At one time I have this number represented as NSString and I need to convert it to long double. I see that the only API I have is
[myString doubleValue];
I don't see a longDoubleValue.
Trying to convert this number using doubleValue...
long double x = (long double)[#"3765765765E933" doubleValue];
gives me inf and the number in question is a legit long double value, as these numbers can go up to 1.18973149535723176502E+4932.
How do I do that?
Perhaps create a category on NSString yourself
NSArray *array = [myString componentsSeparatedByString:#"E"];
long double mantis = (long double)[array[0] doubleValue];
long double exponent = (long double)[array[1] doubleValue];
return mantis * exponent;
There will possibly be a loss of data though
edit
It would seem that long double on iOS is the same size as double. Maybe you will need a custom class to hold such large numbers.
You could probably do:
long double s = strtold(myString.UTF8String, NULL);
but if sizeof(long double) is the same as sizeof(double) as mag_zbc says, you might still get Inf.
If you want to go the pow() route, there is powl() which takes and returns long doubles.
You can do this using the C library sscanf function. Here is a sample Objective-C wrapper:
long double stringToLongDouble(NSString *str)
{
long double result = 0.0L;
int ret = sscanf(str.UTF8String, "%Lg", &result);
if (ret != 1)
{
// Insert your own error handling here, using NSLog for demo
NSLog(#"stringToLongDouble: could not parse '%#' as long double", str);
return 0.0L;
}
return result;
}
The return from sscanf will be 1 if it succeeds. For possible error returns see the documentation (man 3 scanf in Terminal) and you need to decide how to handle these, the above example just does an NSLog.
Note: The size & precision of long double may vary by platform/OS version. The above has been tested with your value on El Capitan and iOS 10 (simulator only) using Xcode 8.
HTH
In fact the answer of mag_zbc is almost there. The last line is incorrect.
Considering that the string has exponent, the correct is:
- (long double)longDoubleValue {
NSArray *array = [string componentsSeparatedByString:#"E"];
long double mantis = (long double)[array[0] doubleValue];
long double exponent = (long double)[array[1] doubleValue];
long double multiplier = powl(10.0L, exponent);
return mantis * multiplier;
}

How can I count decimal digits?

I have to count how many decimal digits are there in a double in Xcode 5. I know that I must convert my double in a NSString, but can you explain me how could I exactly do? Thanks
A significant problem is that a double has a fractional part which has no defined length. If you know you want, say, 3 fractional digits, you could do:
[[NSString stringWithFormat:#"%1.3f", theDoubleNumber] length]
There are more elegant ways, using modulo arithmetic or logarithms, but how elegant do you want to be?
A good method could be to take your double value and, for each iteration, increment a counter, multiply your value by ten, and constantly check if the left decimal part is really near from zero.
This could be a solution (referring to a previous code made by Graham Perks):
int countDigits(double num) {
int rv = 0;
const double insignificantDigit = 8;
double intpart, fracpart;
fracpart = modf(num, &intpart);
while ((fabs(fracpart) > 0.000000001f) && (rv < insignificantDigit))
{
num *= 10;
fracpart = modf(num, &intpart);
rv++;
}
return rv;
}
You could wrap the double in an instance of NSNumber and get an NSString representation from the NSNumber instance. From there, calculating the number of digits after the decimal could be done.
One possible way would be to implement a method that takes a double as an argument and returns an integer that represents the number of decimal places -
- (NSUInteger)decimalPlacesForDouble:(double)number {
// wrap double value in an instance of NSNumber
NSNumber *num = [NSNumber numberWithDouble:number];
// next make it a string
NSString *resultString = [num stringValue];
NSLog(#"result string is %#",resultString);
// scan to find how many chars we're not interested in
NSScanner *theScanner = [NSScanner scannerWithString:resultString];
NSString *decimalPoint = #".";
NSString *unwanted = nil;
[theScanner scanUpToString:decimalPoint intoString:&unwanted];
NSLog(#"unwanted is %#", unwanted);
// the number of decimals will be string length - unwanted length - 1
NSUInteger numDecimalPlaces = (([resultString length] - [unwanted length]) > 0) ? [resultString length] - [unwanted length] - 1 : 0;
return numDecimalPlaces;
}
Test the method with some code like this -
// test by changing double value here...
double testDouble = 1876.9999999999;
NSLog(#"number of decimals is %lu", (unsigned long)[self decimalPlacesForDouble:testDouble]);
results -
result string is 1876.9999999999
unwanted is 1876
number of decimals is 10
Depending on the value of the double, NSNumber may do some 'rounding trickery' so this method may or may not suit your requirements. It should be tested first with an approximate range of values that your implementation expects to determine if this approach is appropriate.

Odd atoi(char *) issue

I'm experiencing a very odd issue with atoi(char *). I'm trying to convert a char into it's numerical representation (I know that it is a number), which works perfectly fine 98.04% of the time, but it will give me a random value the other 1.96% of the time.
Here is the code I am using to test it:
int increment = 0, repetitions = 10000000;
for(int i = 0; i < repetitions; i++)
{
char randomNumber = (char)rand()%10 + 48;
int firstAtoi = atoi(&randomNumber);
int secondAtoi = atoi(&randomNumber);
if(firstAtoi != secondAtoi)NSLog(#"First: %d - Second: %d", firstAtoi, secondAtoi);
if(firstAtoi > 9 || firstAtoi < 0)
{
increment++;
NSLog(#"First Atoi: %d", firstAtoi);
}
}
NSLog(#"Ratio Percentage: %.2f", 100.0f * (float)increment/(float)repetitions);
I'm using the GNU99 C Language Dialect in XCode 4.6.1. The first if (for when the first number does not equal the second) never logs, so the two atoi's return the same result every time, however, the results are different every time. The "incorrect results" seemingly range from -1000 up to 10000. I haven't seen any above 9999 or any below -999.
Please let me know what I am doing wrong.
EDIT:
I have now changed the character design to:
char numberChar = (char)rand()%10 + 48;
char randomNumber[2];
randomNumber[0] = numberChar;
randomNumber[1] = 0;
However, I am using:
MAX(MIN((int)(myCharacter - '0'), 9), 0)
to get the integer value.
I really appreciate all of the answers!
atoi expects a string. You have not given it a string, you have given it a single char. A string is defined as some number of characters ended by the null character. You are invoking UB.
From the docs:
If str does not point to a valid C-string, or if the converted value would be out of the range of values representable by an int, it causes undefined behavior.
Want to "convert" a character to its integral representation? Don't overcomplicate things;
int x = some_char;
A char is an integer already, not a string. Don't think of a single char as text.
If I'm not mistaken, atoi expects a null-terminated string (see the documentation here).
You're passing in a single stack-based value, which does not have to be null-terminated. I'm extremely surprised it's even getting it right: it could be reading off hundreds of garbage numbers into eternity, if it never finds a null-terminator. If you just want to get the number of a single char (as in, the numeric value of the char's human-readable representation), why don't you just do int numeric = randomNumber - 48 ?

unichar* to NSString, get the length

I am trying to create an NSString object from a const unichar buffer where I don't know the length of the buffer.
I want to use the NSString stringWithCharacters: length: method to create the string (this seems to work), but please can you help me find out the length?
I have:
const unichar *c_emAdd = [... returns successfully from a C++ function...]
NSString *emAdd = [NSString stringWithCharacters:c_emAdd length = unicharLen];
Can anyone help me find out how to check what unicharLen is? I don't get this length passed back to me by the call to the C++ function, so I presume I'd need to iterate until I find a terminating character? Anyone have a code snippet to help? Thanks!
Is your char buffer null terminated?
Is it 16-bit unicode?
NSString *emAdd = [NSString stringWithFormat:#"%S", c_emAdd];
Your unichars should be null terminated so you when you reach two null bytes (a unichar = 0x0000) in the pointer you will know the length.
unsigned long long unistrlen(unichar *chars)
{
unsigned long long length = 0llu;
if(NULL == chars) return length;
while(NULL != chars[length])
length++;
return length;
}
//...
//Inside Some method or function
unichar chars[] = { 0x005A, 0x0065, 0x0062, 0x0072, 0x0061, 0x0000 };
NSString *string = [NSString stringWithCharacters:chars length:unistrlen(chars)];
NSLog(#"%#", string);
Or even simpler format with %S specifier

Find Character String In Binary Data

I have a binary file I've loaded using an NSData object. Is there a way to locate a sequence of characters, 'abcd' for example, within that binary data and return the offset without converting the entire file to a string? Seems like it should be a simple answer, but I'm not sure how to do it. Any ideas?
I'm doing this on iOS 3 so I don't have -rangeOfData:options:range: available.
I'm going to award this one to Sixteen Otto for suggesting strstr. I went and found the source code for the C function strstr and rewrote it to work on a fixed length Byte array--which incidentally is different from a char array as it is not null terminated. Here is the code I ended up with:
- (Byte*)offsetOfBytes:(Byte*)bytes inBuffer:(const Byte*)buffer ofLength:(int)len;
{
Byte *cp = bytes;
Byte *s1, *s2;
if ( !*buffer )
return bytes;
int i = 0;
for (i=0; i < len; ++i)
{
s1 = cp;
s2 = (Byte*)buffer;
while ( *s1 && *s2 && !(*s1-*s2) )
s1++, s2++;
if (!*s2)
return cp;
cp++;
}
return NULL;
}
This returns a pointer to the first occurrence of bytes, the thing I'm looking for, in buffer, the byte array that should contain bytes.
I call it like this:
// data is the NSData object
const Byte *bytes = [data bytes];
Byte* index = [self offsetOfBytes:tag inBuffer:bytes ofLength:[data length]];
Convert your substring to an NSData object, and search for those bytes in the larger NSData using rangeOfData:options:range:. Make sure that the string encodings match!
On iPhone, where that isn't available, you may have to do this yourself. The C function strstr() will give you a pointer to the first occurrence of a pattern within the buffer (as long as neither contain nulls!), but not the index. Here's a function that should do the job (but no promises, since I haven't tried actually running it...):
- (NSUInteger)indexOfData:(NSData*)needle inData:(NSData*)haystack
{
const void* needleBytes = [needle bytes];
const void* haystackBytes = [haystack bytes];
// walk the length of the buffer, looking for a byte that matches the start
// of the pattern; we can skip (|needle|-1) bytes at the end, since we can't
// have a match that's shorter than needle itself
for (NSUInteger i=0; i < [haystack length]-[needle length]+1; i++)
{
// walk needle's bytes while they still match the bytes of haystack
// starting at i; if we walk off the end of needle, we found a match
NSUInteger j=0;
while (j < [needle length] && needleBytes[j] == haystackBytes[i+j])
{
j++;
}
if (j == [needle length])
{
return i;
}
}
return NSNotFound;
}
This runs in something like O(nm), where n is the buffer length, and m is the size of the substring. It's written to work with NSData for two reasons: 1) that's what you seem to have in hand, and 2) those objects already encapsulate both the actual bytes, and the length of the buffer.
If you're using Snow Leopard, a convenient way is the new -rangeOfData:options:range: method in NSData that returns the range of the first occurrence of a piece of data. Otherwise, you can access the NSData's contents yourself using its -bytes method to perform your own search.
I had the same problem.
I solved it doing the other way round, compared to the suggestions.
first, I reformat the data (assume your NSData is stored in var rawFile) with:
NSString *ascii = [[NSString alloc] initWithData:rawFile encoding:NSAsciiStringEncoding];
Now, you can easily do string searches like 'abcd' or whatever you want using the NSScanner class and passing the ascii string to the scanner. Maybe this is not really efficient, but it works until the -rangeOfData method will be available for iPhone also.

Resources