2

I tried this:

NSInteger numberFinal = 100000000000000000 + ((float)arc4random() / UINT32_MAX) * (999999999999999999 - 100000000000000000);

but it returns zero... I don't want to specify the range, but just want any number with 18 digits...

Goppinath
  • 10,569
  • 4
  • 22
  • 45
user2014474
  • 1,117
  • 5
  • 19
  • 36

5 Answers5

6

For your requirement, as @duDE mentioned you can't use a NSInteger to save 18 digit number, but there is a solution using NSString.

NSString *eighteenDigitNumberString = [[NSNumber numberWithInt:1 + arc4random_uniform(9)] stringValue];

for (int i = 0; i < 17; i++) {

    eighteenDigitNumberString = [eighteenDigitNumberString stringByAppendingString:[[NSNumber numberWithInt:arc4random_uniform(10)] stringValue]];
}

NSLog(@"eighteenDigitNumberString : %@", eighteenDigitNumberString);

There we go, no need to explain everything is straightforward.

EDITED: if you really want a long long value you can do so:

long long eighteenDigitNumberLongLong = [eighteenDigitNumberString longLongValue];  

EDITED: To avoid the leading 0 the initial string has been initiated with a non-zero number and the loop is running only 17 times.

Goppinath
  • 10,569
  • 4
  • 22
  • 45
  • 1
    Note that using arc4random() with a modulo can result in modulo bias if the upper bound is not a multiple of 2 (I know yours is). But in general because of this, I typically recommend the use of `arc4random_uniform(x)`. http://stackoverflow.com/a/6194148/3708242 – wottle Aug 29 '14 at 12:06
  • But the OP did not ask for a `NSString`. – zaph Aug 29 '14 at 12:17
  • Also, I believe the OP does not want a 0 in the first digit spot, so you should account for that. – wottle Aug 29 '14 at 12:32
  • Does this mean that every time I do [eighteenDigitNumberString intValue] I get maximum 10 digits? – user2014474 Aug 29 '14 at 17:13
  • ya... because, depending on your CPU architecture your NSInteger max value will vary. Therefore if you cast it to a integer you will loose your precisions. You might get 10 instead of 18 in your case. – Goppinath Aug 29 '14 at 17:19
2

As the maximum value of an NSInteger is NSIntegerMax, you cann't use NSInteger for your purpose:

enum {
   NSNotFound = NSIntegerMax
};

Prior to OS X v10.5, NSNotFound was defined as 0x7fffffff. This is 2147483647 (decimal).

If you need "any number" with 18 digits (as @A-Live assumes), you can take NSFloat for example.

Leo Chapiro
  • 13,678
  • 8
  • 61
  • 92
  • 1
    He wants "any number" with 18 digits, sure using `NSInteger` is a mistake but I don't think saying "impossible" is a good answer, please guide him to the types he could use. – A-Live Aug 29 '14 at 11:57
2

A 18 digit integer will require a long long type.

Create two 9 digit random numbers, multiple one by 10^9 and add to the other.

const u_int32_t digits9 = 1000000000;
u_int32_t ms = arc4random_uniform(digits9);
u_int32_t ls = arc4random_uniform(digits9);
unsigned long long random18 = ((unsigned long long)ms * digits9) + ls;

NSLog(@"Example random18: %018llu", random18);

Output:

Example random18: 501895974656079554

If the number must have a leading non zero digit:

const u_int32_t digits81 = 100000000;
const u_int32_t digits89 = 900000000;
const u_int32_t digits9 = 1000000000;

u_int32_t ms = arc4random_uniform(digits89) + digits81;
u_int32_t ls = arc4random_uniform(digits9);
unsigned long long random18 = ((unsigned long long)ms * digits9) + ls;
zaph
  • 111,848
  • 21
  • 189
  • 228
1

If you need strictly 18 digits it would be better to use this code:

NSString *stringNumber = [NSString string];

for (int i = 0; i < 18; i++) {
    if (i == 0) {   
        stringNumber = [stringNumber stringByAppendingString:[NSString stringWithFormat:@"%@", @(arc4random_uniform(9) + 1)]];
    } else {
        stringNumber = [stringNumber stringByAppendingString:[NSString stringWithFormat:@"%@", @(arc4random_uniform(10))]];
    }
}

long long value = stringNumber.longLongValue;

You need the first condition because with the possibility of 0.1 you may receive 0 as the first digit, then your 18-digit integer would become 17-digit, with 0.01 possibility - 16-digit integer etc.

Nikita Shytyk
  • 408
  • 7
  • 16
0

You're getting into unsigned long long territory...

#define ARC4RANDOM_MAX      0x100000000

float val = ((double)arc4random() / ARC4RANDOM_MAX);
unsigned long long numberToAdd = val * (900000000000000000-1);
unsigned long long numberFinal = 100000000000000000 + numberToAdd;

NSLog( @"value = %llu", numberFinal);
wottle
  • 13,095
  • 4
  • 27
  • 68
  • There is only 32-bits of randomness. – zaph Aug 29 '14 at 12:26
  • Where do I use the mod operator. The modulo bias doesn't apply since I'm not doing a mod operator. I do agree with your other comment that you only get 32 bits of random, but figured that would be sufficient for what he is doing. I think constructing the 18 digit number one at a time is probably the easiest approach though. – wottle Aug 29 '14 at 12:31
  • My error on mod. But providing only 32 bits or randomness is just incorrect. – zaph Aug 29 '14 at 12:45